[余談] Tkinter に挑戦
現在稼働している GUI アプリケーションは PyQt4 を使って(見様見真似で)作ったものでした。
オペレーターの記録など、入力の一部はプルダウンメニューから選択する仕様でしたが、バーコードリーダーの活用が進んで各人の名札にQRコードを印刷して読ませるように変えたいと思います。
サーバーに置いたオペレータのリストを更新する工数が無くなり、入力ミスも減ると期待しています。
PyQt4で作った画面を変える必要があり、数年ぶりに調べてみるとPyQt5 に替えないといけない様子でした。既にインストール済のPyQt4で作ることも考えましたが、今後のことを考えると心配です。
Raspberry Pi だけで開発出来る点も評価して、Python 標準の Tkinter を使ってみようと勉強中です。
個々のウィジェット毎にコーディングが必要ですが、GUI画面を作る機会が少ない現状で開発環境の維持コスト(手間)を考えれば、Tkinter で良いと考えています。
当面の目標
目先は、以下を目標にします。
1.ウィンドウ内の任意の位置に複数のフレームを配置出来ること
2.フレーム内に以下ウィジェットを配置し利用出来ること
ラベル、メッセージ、ボタン、テキストボックス
3.画像を表示、切り替え出来ること
4.main 処理との間でデータやボタン操作の連携が出来ること
5.一定の時間間隔で表示更新が出来ること
6.ウィンドウにファイル・ドロップで動作する仕組みを作れること
進捗
タイトル図のような画面が出来ています。
沢山のWebページにお世話になりました。ありがとうございます。
フレーム毎に色を変えているのでタイル張りのようです。
出力欄も1つのフレームなので、合計4フレームです。
最終的に統一した色にするつもりです。
進捗は、目標の3番目の途中と言ったところでしょうか、4番目までは時間の問題だと思います。
最後に現時点のコードを紹介します。
もう少し、フレーム毎の階層構造を識別しやすく書ければ助かるのですが・・・お気づきの点などありましたらご教示お願いいたします。
(コーディングと動作確認時の環境はRaspberry Pi 4B、Spyder3 です。)
私の場合、使うウィジェットが限定的なので、しばらく使わない期間があったとしても、動作確認済のコードさえあれば何とかなりそうな気がします。
タイトル図時点のコード
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import tkinter as tk
class Application(tk.Frame):
def __init__(self,master):
super().__init__(master)
#self.pack()
self.place()
self.master.geometry("600x400")
self.master.title("Tkinter with Class (uPyC)")
self.create_widgets()
# Create Widgets function
def create_widgets(self):
# フレーム1の作成 (上左)
frame1 = tk.Frame( # frame1インスタンスを作成
self.master, # root要素であるウィンドウを指定
background="gray", # 背景色を指定
borderwidth=0, # ボーダーの幅を指定
#relief="sunken", # ボーダーの浮き彫りを指定
width=400, # 幅をpixel単位で指定
height=350, # 高さをpixel単位で指定
)
label1 = tk.Label(frame1,text="Tkinter に挑戦 1",font=("",14))
label1.place(x=10,y=10)
self.fig = tk.PhotoImage(file="/home/pi/Desktop/RPi1.png")
canvas = tk.Canvas(frame1,bg="white", width=380, height=290)
canvas.place(x=10, y=50)
canvas.create_image(5, 0, image=self.fig, anchor=tk.NW)
#frame1.pack() # frame1インスタンスを配置
frame1.place(x=0,y=0) # frame1インスタンスを配置
# フレーム2の作成 (上右)
frame2 = tk.Frame( # frame1インスタンスを作成
self.master, # root要素であるウィンドウを指定
background="light sky blue", # 背景色を指定
borderwidth=0, # ボーダーの幅を指定
#relief="sunken", # ボーダーの浮き彫りを指定
width=200, # 幅をpixel単位で指定
height=350, # 高さをpixel単位で指定
)
label2 = tk.Label(frame2, text="入力欄 ↓")
label2.place(x=10,y=20)
self.box1 = tk.Entry(frame2, width=21)
self.box1.place(x=10,y=50)
self.button1 = tk.Button(frame2,text="追加", width=5, height=1, bg="SeaGreen1", command=self.appen)
self.button1.place(x=115,y=80)
label3 = tk.Label(frame2, text="出力欄 ↓")
label3.place(x=10,y=100)
self.frame21 = tk.Frame(
frame2, # root要素であるウィンドウを指定
background="snow", # 背景色を指定
borderwidth=2, # ボーダーの幅を指定
relief="sunken", # ボーダーの浮き彫りを指定
width=180, # 幅をpixel単位で指定
height=190, # 高さをpixel単位で指定
)
#self.lbl = "ここに表示します"
self.msg = 'ここに追加します。\n'
self.ms1 = tk.Message(self.frame21,width=176, text=self.msg, bg="snow")
self.ms1.place(x=0,y=0)
self.frame21.place(x=10,y=150)
#frame1.pack() # frame1インスタンスを配置
frame2.place(x=400,y=0) # frame1インスタンスを配置
# フレーム3の作成 (下中央)
frame3 = tk.Frame( # frame1インスタンスを作成
self.master, # root要素であるウィンドウを指定
background="khaki", # 背景色を指定
borderwidth=0, # ボーダーの幅を指定
#relief="sunken", # ボーダーの浮き彫りを指定
width=600, # 幅をpixel単位で指定
height=50, # 高さをpixel単位で指定
)
self.buttonq = tk.Button(frame3,text="終 了", width=10, height=1, bg="LightPink1", command=self.master.destroy)
self.buttonq.place(x=10,y=10)
self.upyc = tk.PhotoImage(file="uPyC.png")
canvas = tk.Canvas(frame3,bg="white", width=40, height=40)
canvas.place(x=550, y=4)
canvas.create_image(0, 0, image=self.upyc, anchor=tk.NW)
#frame1.pack() # frame1インスタンスを配置
frame3.place(x=0,y=350) # frame1インスタンスを配置
def appen(self):
c = self.box1.get()
print(c)
cc = c + '\n'
self.msg += cc
self.ms1 = tk.Message(self.frame21,width=176, text=self.msg, bg="snow")
self.ms1.place(x=0,y=0)
def main():
root = tk.Tk()
app = Application(master=root)#Inheritクラスの継承!
app.mainloop()
if __name__ == "__main__":
main()
以上、何らかお役に立てれば幸いです。