Python環境におけるTkinterウィジェットの基本と、イベントについて簡単なまとめ。
ウィジェット(Widget)
Tkinterを使用してGUIアプリケーションを構築する際には、ウィジェット(Widget)と呼ばれる様々なコンポーネントを使用して画面を構成していくことになる。ウィジェットはTkinterで画面上に表示するすべてのものである。
Tkinter(tk)とTtk(ttk)
Ttk(ttk)は、Tk 8.5 で導入された Tk のテーマ付きウィジェット。ボタンやエントリなどtkにもttkにも同じウィジェット名で定義されているので、既存のtkinterインポートを以下のようにしておけば、一部のウィジェット (Button
, Checkbutton
, Entry
, Frame
, Label
, LabelFrame
, Menubutton
, PanedWindow
, Radiobutton
, Scale
, Scrollbar
) は簡単に Ttk ウィジェットに置き換えられる。
from tkinter import *
fromt kinter.ttk import *
主な違いとしてttkでは外観を制御する部分がウィジェットから分離されており、ttk.Styleで独自の外観を指定しウィジェットのStyleを上書きすることができる。
主要なウィジェットの例
ウィンドウ (Window):
- Tkinterアプリケーションのルートとなるウィンドウ。
Tk()
クラスを使用して作成されます。
フレーム (Frame):
- ウィンドウ内に配置されるコンテナであり、他のウィジェットをグループ化してくれる。
Frame()
クラスを使用して作成されます。
ボタン (Button):
- クリック可能なボタンで、ユーザーがアクションを実行できるようにする。
Button()
クラスを使用して作成されます。
ラベル (Label):
- 文字列や画像などの静的なテキストを表示します。
Label()
クラスを使用して作成されます。
テキストボックス (Entry):
- ユーザーがテキストを入力できる入力フィールドです。
Entry()
クラスを使用して作成されます。
より詳細なウィジェットの一覧はこちらをどうぞ
ウィジェットの作成
Python環境におけるそれぞれのウィジェットはPythonのオブジェクトである。ウィジェットをインスタンス化するときは、その親をパラメーターとしてウィジェット クラスに渡す必要がある。ただしTk()で作成するルートウィンドウは親を持たない。
root = Tk() # ルートウィンドウ
frame = ttk.Frame(root) # ルート-フレーム
label = ttk.Label(frame) # ルート-フレーム-ラベル
Frameからみた親はrootであり、Frameは子である。ただしLabelから見た時Frameは親である。同じウィジェットであっても親にも子にもなりえる。
ウィジェット情報の取得
winfo
系のメソッドは、Tkinterウィジェットの情報を取得できる。代表的なものを以下に記載する。
winfo_children()
- Tkinterウィジェットの子ウィジェットをリストとして返す。
- 子ウィジェットは、その親ウィジェットの下に配置されているすべてのウィジェット。
import tkinter as tk
root = tk.Tk()
frame = tk.Frame(root)
label1 = tk.Label(frame, text="Label 1")
label2 = tk.Label(frame, text="Label 2")
button = tk.Button(frame, text="Button")
# frameの子ウィジェットを取得
children = frame.winfo_children()
print(children) # [label1, label2, button]
winfo_parent()
- ウィジェットの親ウィジェットを返す。
- 親ウィジェットは、指定したウィジェットが配置されている親のウィンドウやフレーム。
import tkinter as tk
root = tk.Tk()
label = tk.Label(root, text="Hello, World!")
# labelの親ウィジェットを取得
parent = label.winfo_parent()
print(parent) # Tk()
winfo_width()/winfo_height()
winfo_width()
は、ウィジェットの幅(ピクセル単位)を取得する。winfo_height()
は、ウィジェットの高さ(ピクセル単位)を取得する。
import tkinter as tk
root = tk.Tk()
label = tk.Label(root, text="Hello, World!")
# labelの幅と高さを取得
width = label.winfo_width()
height = label.winfo_height()
print("Width:", width, "Height:", height)
winfo_x()/winfo_y()
winfo_x()
は、ウィジェットのX座標(ウィンドウの左上隅からの相対位置)を取得する。winfo_y()
は、ウィジェットのY座標(ウィンドウの左上隅からの相対位置)を取得する。
import tkinter as tk
root = tk.Tk()
label = tk.Label(root, text="Hello, World!")
label.pack()
# labelのX座標とY座標を取得
x = label.winfo_x()
y = label.winfo_y()
print("X:", x, "Y:", y)
winfo_rootx()/winfo_rooty()
winfo_rootx()
は、ウィジェットのX座標(スクリーンの左上隅からの絶対位置)を取得する。winfo_rooty()
は、ウィジェットのY座標(スクリーンの左上隅からの絶対位置)を取得する。
import tkinter as tk
root = tk.Tk()
label = tk.Label(root, text="Hello, World!")
label.pack()
# labelの画面全体における絶対X座標とY座標を取得
root_x = label.winfo_rootx()
root_y = label.winfo_rooty()
print("Root X:", root_x, "Root Y:", root_y)
イベント処理
他の言語のように、ボタンクリックなどのイベントを処理できる。例えばButtonウィジェットならcommandオプションにコールバック関数を指定することで簡単にクリック時の処理を追加できる。
import tkinter as tk
def button_clicked():
print("Button clicked!")
# アプリケーションのウィンドウを作成
root = tk.Tk()
# ボタンウィジェットを作成し、クリック時にbutton_clicked関数を呼び出すイベントハンドラを設定
button = tk.Button(root, text="Click me", command=button_clicked)
button.pack()
# イベントループの開始
root.mainloop()
バインドでイベントを追加する
例えばラベルのように、クリック時のオプション引数が標準で用意されていない場合、bindを利用してユーザー操作に応答できる。
import tkinter as tk
def label_clicked(event):
print("Label clicked!")
root = tk.Tk()
label = tk.Label(root, text="Click me")
label.pack()
# ラベルがクリックされたときにlabel_clicked関数を呼び出すイベントのバインド
label.bind("<Button-1>", label_clicked)
root.mainloop()
"<Button-1>"
はTkinterでマウスのボタンを表すイベント文字列であり、左クリックを表している。
イベント文字列
イベント文字列は、Tkinterで特定のイベントを表すために使用される形式化された文字列であり、これらの文字列はウィジェットにバインドされたり、ウィジェットが特定のイベントに反応したりするときに使用される。
イベント文字列は、次の形式を取る
"<MODIFIER-MODIFIER-TYPE-DETAIL>"
MODIFIER
はオプションで、修飾キー(例えば、Controlキー、Shiftキーなど)を表す。TYPE
はイベントの種類を表し、”ButtonPress”、”Motion”、”KeyPress”、”KeyRelease”などがある。DETAIL
はイベントの詳細を表し、ボタンの番号やキーの名前などが含まれる。
イベント文字列の例
<Button-1>
: マウスの左ボタンがクリックされたときに発生するイベント。<KeyPress-a>
: キーボードの”A”キーが押されたときに発生するイベント。<Control-Shift-KeyPress-q>
: Ctrl + Shift + Qが押されたときに発生するイベント。<Motion>
: マウスがウィジェット上で移動したときに発生するイベント。
MODIFIER、TYPE、DETAILのイベント一覧
一般的なイベント文字列で使用されるMODIFIER
、TYPE
、DETAIL
の使いそうなものの一覧。あとでもう少し掘り下げたまとめも作る予定。
MODIFIER(修飾キー)
イベント文字列 | イベント内容 |
<Control> | Ctrlキーが押されているときに発生するイベント |
<Shift> | Shiftキーが押されているときに発生するイベント |
<Alt> | Altキーが押されているときに発生するイベント |
<Meta> | Metaキー(WindowsではWindowsキー、macOSではCommandキー)が押されているときに発生するイベント |
<Button-1> | マウスの左ボタンがクリックされたときに発生するイベント |
<Button-2> | マウスの中央ボタンがクリックされたときに発生するイベント |
<Button-3> | マウスの右ボタンがクリックされたときに発生するイベント |
TYPE(イベントの種類)
イベント文字列 | イベント内容 |
<Motion> | マウスがウィジェット上で移動したときに発生するイベント |
<KeyPress> | キーが押されたときに発生するイベント |
<KeyRelease> | キーが離されたときに発生するイベント |
<Enter> | マウスがウィジェットに入ったときに発生するイベント |
<Leave> | マウスがウィジェットから出たときに発生するイベント |
<ButtonPress> | ユーザーがマウスボタンを押すと生成されるイベント |
<ButtonRelease> | ユーザーがマウスボタンを離すと生成されるイベント |
DETAIL(イベントの詳細)
DETAILの部分には、イベントに応じて入る文字列が変わる。
ButtonPressまたはButtonReleaseイベントの場合、マウスボタンの番号 (1
は左、2
は中央、3
は右、~ 5) になる。
KeyPressまたはKeyReleaseイベントの場合、キーボード上の特定のキー名になる。たとえばa,b,c,Enterなどである。