目次
pythonでWindowsのGUI画面を作る
めったにありませんが。
PythonでWindowsのGUIプログラムを作りたいときの話題です。
WindowsのGUI画面を使う「tkinter」
PythonでWindowsのGUI画面を使う手軽な選択肢「tkinter」の話題です。
tkinterは、Python標準のGUIライブラリで、 Tcl/Tk の Python インタフェースです。
GUIは古く感じるデザインで、設計が古いせいか、ちょっと癖があります。
でも、「ちょこっと試す」ためのGUIを構築するには便利なライブラリです。
今回は、よく使う以下のWidgetに絞って、ごくシンプルな入力画面を作ります。。
- Entry : 1行テキスト入力(テキストボックス)
- Text : 複数行テキスト入力(テキストエリア)
- OptionMenu : プルダウンメニュー
- CheckButton : チェックボックス
- Button : サブミットボタン
他にもいろいろあります。
必要になったら、こちらのドキュメントとかを参考にします。
tkinterのレイアウトのめんどくささを軽減するクラス
tkinterはレイアウトがめんどくさいです。
GUIの設計画面はありません。
配置する座標をX・Yの座標で指定して微調整が必要ですので。
なので、部品を1行ずつペタペタ書いていけば、それなりの画面になる使い方をするためのクラスを作ってみます。
class_tkinter_use.py
import tkinter as tk from tkinter import messagebox class Gui: def __init__(self, title='Demo window'): self.window_width = 640 self.window_height = 480 self.left_space = 20 self.right_space = 30 self.top_space = 20 self.row_span = 50 self.col_span = 10 self.label_width = 80 self.x = self.left_space self.y = self.top_space self.root = tk.Tk() self.root.title(title) self.root.geometry(str(self.window_width) + "x" + str(self.window_height)) self.parts_list = [] def text_box(self, label): x = self.x y = self.y w = self.label_width pw = 80 lb = tk.Label(text=label) lb.place(x=x, y=y) box = tk.Entry(width=pw) box.place(x=x + w + self.col_span, y=y) self.y = self.y + self.row_span return box def text_area(self, label): x = self.x y = self.y w = self.label_width pw = 68 lb = tk.Label(text=label) lb.place(x=x, y=y) box = tk.Text(width=pw, height=6) box.place(x=x + w + self.col_span, y=y) self.y = self.y + self.row_span + 50 return box def check_box(self, label, boolvar): x = self.x y = self.y w = self.label_width box = tk.Checkbutton(text=label, variable=boolvar) box.place(x=x + w + self.col_span, y=y) self.y = self.y + self.row_span return box def bool_var(self): return tk.BooleanVar() def combo_box(self, label, values, select): x = self.x y = self.y w = self.label_width lb = tk.Label(text=label) lb.place(x=x, y=y) optionList = values variable = tk.StringVar(self.root) variable.set(optionList[0]) box = tk.OptionMenu(self.root, variable, *optionList, command=select) box.place(x=x + w + self.col_span, y=y) self.y = self.y + self.row_span return box def button(self, label, command): button = tk.Button(text=label, command=command) button.place(x=self.x, y=self.y) self.y = self.y + self.row_span return button def show(self): self.root.mainloop() def msgbox(self, msg1, msg2): messagebox.showinfo(msg1, msg2) def textindex1(self): return '1.0' def textindex2(self): return 'end -1c'
簡単に捕捉します。
Windowsサイズ、左右トップの各マージンは固定にしています。
数字べた書きですが・・まあ、個人用なので。
self,xとself.yに「次に描画する部品の座標」を保持して、部品の描画後に更新します。
作成したクラスを使って簡単な画面をつくってみる
パーツをぺたぺたのひとつずつ配置し、ボタンを押したときに入力値を取得して、メッセージボックスに表示します。
ソースコードはこんな感じです。
import class_tkinter_use as gt def button_click(): s = t1.get() + "\n" + selected + "\n" + str(chkValue.get()) + \ "\n" + t4.get(wdw.textindex1(), wdw.textindex2()) wdw.msgbox("クリックイベント", s) def select(value): global selected selected = value wdw = gt.Gui() t1 = wdw.text_box(label='入力部品1') oplist = [ "選択するもの1", "選択するもの2" ] selected = oplist[0] chkValue = wdw.bool_var() chkValue.set(True) t2 = wdw.combo_box(label='入力部品2', values=oplist, select=select) t3 = wdw.check_box(label='入力部品3', boolvar=chkValue) t4 = wdw.text_area(label='入力部品4') b1 = wdw.button(label='実行ボタン', command=button_click) wdw.show()
各部品をひとつずつ配置してます。
実行すると、以下のような画面を表示します。
適当に入力したり、選択しなおしてみます。
実行ボタンを押してみます。
入力値は、取得できているみたいです。
データの取得補足:テキストボックス
ikinterのwidgetでデータを取得する方法を簡単にまとめておきます。
まず、1行入力のテキストボックス(Entry)は簡単です。
t1.get()
のように、get()を呼ぶだけです。
これが複数行テキスト入力(Text)になると、get()の引数に、開始行(index1)と終了行(index2)の指定が必要なのは、前に書きましたので飛ばします。
データの取得補足:プルダウンリスト
プルダウンリスト(OptionMenu)は、状態が変化したときに呼び出されるコールバック関数を用意して、その中でglobal変数に値をセットして、それを参照するみたいなことをする必要があります。
上記のソースなら、この部分です。
def select(value): global selected selected = value
なのでボタンクリックで参照しているのは、selectedなのです。
データの取得補足:チェックボックス
チェックボックス(CheckButton)の場合は、状態をセットする参照用の変数を定義してやる必要があります。
それがこの部分です。
chkValue = wdw.bool_var()
chkValue.set(True)
t3 = wdw.check_box(label='入力部品3', var=chkValue)
この場合だと、チェックボックスが選択されたり、解除されたりしたときに、chkValueの値が変化します。
なので。
chkValue.get()
でとりだせているわけです。
とりあえず、適当なクラスですが、ちょっとした動作確認の画面には重宝してます。
今回はこんなところで。
ではでは。