Tkinterを使いこなしたい:備忘録(1)
シミュレーションをするときに,条件を変えて再度実行したい,違う条件で表示したい,といった時に,GUIで操作できるようにしてあるとすごく便利です.今回は,PythonにおいてそんなGUIを提供してくれるパッケージ"Tkinter"を用いた自作のラッパークラス"SetParameter"について,備忘録の意味も込めて残しておきます.なお,GUIの表示にはgobjectを用いてGTKを使うこともできますが,Tkinterのほうが簡潔でわかりやすい気がしたので.GTKは軽くチュートリアルをさらった程度です.独学で勉強する人のために,参考になったサイトのリンクをば.
参考:(愛知大学のKenji Arisawaさんが講義で使用している(た?)教材pdfファイル.PythonとTkinterの基本について網羅的で,初心者におすすめ)
(大黒学さんによる,素晴らしいチュートリアル.プログラミング自体が初心者でも,分量は多いが全て身になる.)
The Python GTK+ 3 Tutorial — Python GTK+ 3 Tutorial 3.4 documentation:
(GTKのチュートリアル.英語.勉強になった(簡単とは言ってない))
Glade3 Gtk Python Tutorial:(GTKによるGUI作成支援アプリケーションGladeのチュートリアル.凝った作りにしたい人は勉強する必要があるかも)
パラメータ代入の簡易ダイアログ - SetParameter
ターミナルでカチャカチャカチャ...ッッターン!ってドヤるのもいいけれど,実際のところボタンを押してシミュレーション開始とかしたい.Tkinterを使おう.
同名のモジュールが使えなくなってしまうため推奨されないやり方ですが,
from Tkinter import *
を,スクリプトファイルの先頭に書いておきます.
よく使うクラスSetParameterは,以下のとおりです.
class SetParameter():def show_setting_window(self, parameters, commands):
""" Show a parameter setting window.
parameters: A list of dictionaries {'parameter name': default_value}
commands: A list of dictionary {'name of button': command}
"""
self.root = Tk()
self.root.title('Parameter')
frame1 = Frame(self.root, padx=5, pady=5)
frame1.pack(side='top')
self.entry = []
for i, parameter in enumerate(parameters): # parametersについて
# 左側にラベルを表示
label = Label(frame1, text=parameter.items()[0][0] + ' = ')
label.grid(row=i, column=0, sticky=E)
# 文字入力欄をその右側に表示
self.entry.append(Entry(frame1, width=10))
self.entry[i].grid(row=i, column=1)
self.entry[i].delete(0, END)
# 初期値には辞書parameterの値を代入
self.entry[i].insert(0, parameter.items()[0][1])
# 一番目の入力欄にフォーカス
self.entry[0].focus_set()
frame2 = Frame(self.root, padx=5, pady=5)
frame2.pack(side='bottom')
self.button = []
for i, command in enumerate(commands): # commandsについて
# frame2にボタンを追加.押下時実行関数は辞書の値
self.button.append(Button(frame2, text=command.items()[0][0],
command=command.items()[0][1]))
# ボタンは横に並べていく
self.button[i].grid(row=0, column=i)
self.root.mainloop()
使い方は,コメントにも書いてありますが,
sp = SetParameter()sp.show_setting_window([{'variable1': 200}, {'variable2': 100}],
[{'a': function_a},{'b': function_b},{'c': function_c},
{'quit': sys.exit}])
のように,関数show_setting_windowの引数として,設定したいパラメータを{'表示する変数名': デフォルトの値}とした辞書のリストと,{'ボタンに表示する文字列': 押下時に実行する関数}の辞書のリストを与えることで,任意の個数のパラメータと,ボタンの配置を行うことができます.
代入した値を取り出すときは,
variable1 = sp.entry[0].get()
のようにしてあげれば良いです.以下に,実際に使うときの例を書いておきます.ファイル名はtest.pyとします.
test.py
from Tkinter import *import sys
class SetParameter():
# ~~~ 省略 ~~~ #
def assignment():
global variable1, variable2
variable1 = sp.entry[0].get()
variable2 = sp.entry[1].get()
def print_result():
print "variable1"
print variable1, type(variable1)
print "variable2"
print variable2, type(variable2)
def function_a():
assignment()
print "function_a ..."
print_result()
def function_b():
assignment()
print "function_b ..."
print_result()
def function_c():
assignment()
print "function_c ..."
print_result()
sp = SetParameter()
sp.show_setting_window([{'variable1': 200}, {'variable2': 100}],
[{'a': function_a},{'b': function_b},{'c': function_c},
{'quit': sys.exit}])
これを実行すると,下の画像のようなダイアログが生成されます.
この状態で"a"ボタンを押すと,ターミナルの標準出力(または統合環境等では出力の表示カラム)に
のように表示されるはずです.ちゃんと"a"ボタンを押してfunction_aが実行され,変数の中身が表示されていますね.ここで,変数の中身は文字列ですので,変数の値を計算に用いる場合などは,int(),float()で数値に置き換える必要があることに注意が必要です.
まとめ
いかがでしたでしょうか.他にも使えそうなTkinterのラッパークラスができたら,随時上げてみたいと思います.つっこみや.もっと綺麗に書けるんじゃ?というアドバイスもいただけたらと思います.