Tkinter
大体がほぼ使い捨てのスクリプトレベルのものしか書かないけど、GUIがあった方がいいときもあるかなぁと思いつつ、久しぶりに調べてみたので記録する。
ちゃんとしたGUIアプリにするならイベントとかデータの受け渡しなんかも考えないといけない気がするし、実際に使うときはまだまだ調べながらになるけど、まあとりあえずで作るとき用のメモとしてはこんなものか。
参考:
メモ:
- Tk()でメインウィンドウを生成して、その下に各種widgetを配置していく。
- widgeはテーマ付きのttkの方で生成しとくと、スタイル変更に対応できる感じぽい
- widgeはbutton()などで生成するだけでなく、grid()でちゃんと配置しよう
- bind()でイベントに対するアクションが設定できるが、コールバック関数にはイベントも引数として渡されるので、*argなどでイベントも受け取れるようにしておくといいかな
import sys import tkinter as tk import tkinter.filedialog import tkinter.messagebox import tkinter.ttk as ttk import logging log_format = "[%(levelname)s]%(name)s, %(filename)s, line %(lineno)d, %(funcName)s(), %(message)s" logging.basicConfig(level=logging.INFO, format=log_format) #logger = logging.getLogger(__name__) class TkMainWindow: def __init__(self): self._logger = logging.getLogger(__name__) self._root = tk.Tk() self._root.title("test_window") self._set_menu() self._set_widgets() self._set_event_action() def _set_widgets(self): root = self._root root.rowconfigure(0, weight=1) root.columnconfigure(0, weight=1) # style s = ttk.Style() # s.theme_use("alt") s.configure('MyWidget.TFrame', background='#ccccff') # main_frame main_frame = ttk.Frame(root, padding=(10), style="MyWidget.TFrame") main_frame.grid(row=0, column=0, sticky=(tk.N, tk.W, tk.E, tk.S)) main_frame.columnconfigure(0, weight=1) main_frame.columnconfigure(1, weight=1) main_frame.rowconfigure(0, weight=1) # widgets b1 = ttk.Button(main_frame, text="Button1") b1.grid(row=0, column=0, padx=10) b2 = ttk.Button(main_frame, text="Button2", command=self._button_action) b2.grid(row=0, column=1, padx=10) def _set_menu(self): root = self._root # menu bar menubar = tk.Menu(root) root['menu'] = menubar # menu items menu_file = tk.Menu(menubar, tearoff=0) menu_file_sub = tk.Menu(menu_file, tearoff=0) menu_edit = tk.Menu(menubar, tearoff=0) # File menubar.add_cascade(menu=menu_file, label='File') menu_file.add_command(label="New") menu_file.add_command(label="Open", command=self._open_file) menu_file.add_cascade(menu=menu_file_sub, label="sub") menu_file_sub.add_command(label="sub1") menu_file_sub.add_command(label="sub2") menu_file.add_separator() menu_file.add_command(label="Close", command=self._close_window) # Edit menubar.add_cascade(menu=menu_edit, label='Edit') menu_edit.add_command(label="Edit1") menu_edit.add_command(label="Edit2") def _set_event_action(self): root = self._root # (注意)bindされた関数には、引数としてイベントオブジェクトが渡される root.bind('<Control-q>', self._close_window) def _open_file(self): self._logger.info("call openfile(): return {}".format( tk.filedialog.askopenfilename())) def _button_action(self): self._logger.info("Button pushed") def _close_window(self, *args): self._logger.info("args: {}".format(args)) self._logger.info("Close window") self._root.destroy() def run(self): self._root.mainloop() def main_function(): app = TkMainWindow() app.run() return 0 if __name__ == "__main__": main_function() sys.exit(0)
メモその2_widgetたち:
widget | Description |
---|---|
Frame | - |
Label | 文字や画像の配置 |
Button | 押したときのアクションは関数オブジェクトを渡す |
Checkbutton | - |
Radiobutton | - |
Entry | テキストボックス |
Combobox | プルダウンリスト |
Listbox | 一覧リスト |
Scrollbar | - |
Text | テキストボックス |
Scale | スライダー |
Spinbox | 1 個ずつ動かす系 |
Progressbar | - |
Separator | 仕切り線 |
LabelFrame | ラベル付き Frame |
Panedwindow | |
Notebook | タブわけ |
Treeview |