HOME Python download 書き込む

Appendix 3. Tkinter のデモ スクリプト


1. 初めに

Tkinter は wxPython と並んで Python 上で動作する代表的な GUI です。 どちらを使うかは各人の好みによりますが、一般に、Tkinter の方が プログラムが短くなり、動作が安定しているように思えます。 一方、複雑な GUI を書くには wxPython の方が向いているかもしれません。

Tkinter は名前が示すように Tcl/Tk の wrapper です。Tcl/Tk は OS に依存しない GUI の草分けで、 広く普及しています。他の GUI に手を広げるにしても Tk は押さえておいた方が良いと思います。 さて、Tcl/Tk をダウンロードすると、リファレンス、デモスクリプトが同封されており、また、 Web 上にも解説記事がたくさんあります。それに比べると Tkinter の方は解説記事、デモスクリプト の量が少ないように見受けられます。特にデモスクリプトはほとんど見当たりません。

それならば、Tcl/Tk を使えばいいと思われるかもしれません。しかし、Tk は便利ですが、それを制御する言語の Tcl には紫藤はなじめません。たぶん、そう感じる人が多いので、Tk は Perl, Python, Ruby, scheme などの人気のある 言語に移植されています。

Tkinter をつくった人は Tk のマニュアルがあれば Tkinter は使えると思っていたのか、 マニュアル類は出回っていませんでした。しかし、実際にスクリプトを書いてみるとわかると思いますが、 Tkinter は Tcl/Tk とかなり違い、それなりのリファレンスがないとプログラムを書くことができません。

ようやく最近、Tkinter のマニュアルが充実してきて も出版されました。 Python-Tk によるプログラミングはだんだんとやりやすくなっています。

一方、サンプルコードは Web 上を探してもほとんど見当たりませんでした。 そこで、自身の勉強をかねて、Tcl/Tk に付属してくるデモを Tkinter に翻訳してみました。 翻訳は、なるべくオリジナルのデモと同じ widget ができるようにしました。 この翻訳作業は結構楽しく、また、Tcl/Tk より Tkinter の方がすっきりとプログラムが書けると感じました。 オブジェクト指向は GUI を書くとき大変有効です。

皆様が Python-Tk のプログラムを書くとき、参考にしていただければ幸いです。

2. 使い方

Tkinter_demo.lzh または、 Tkinter_demo.tgz をダウンロードしてどこかのディレクトリに解凍します。その後、解凍したディレクトリに行って、 index.py を立ち上げれば、説明と全てのデモの一覧が表示されるので、その中から選んで試してみてください。
また、それぞれのデモスクリプトは単独でも動作します。例えば、menu.py だけを見たいときはコマンドラインから
>python menu.py
と打ち込めば、menu.py が起動します。

3. 動作環境

Python2.4 + Window XP と Python2.3 + Linux (Debian Sarge) で動作確認をしました。 他の環境でも動作すると思われますが、もし、動作しない場合は takafumi@shido.info にご連絡ください。

4. デモスクリプトの構成

デモスクリプトは template.py にある Demo クラスを用いて作られています。 それぞれのスクリプトにおいて、template.py は `A' として import されています (import template as A)。 A.Demo の主な widget は下の図に示す、self.demo_main_frame, self.demo_frame, self.demo_buttons, および self.code_window です。


5. 通常のスクリプトに変換する方法

self.demo_main_frame を親フレームにするように書き直せば、独立したスクリプトに変換できます。ここでは、 button.py を例にとって説明します。
01:     #! /usr/bin/env python
02:     
03:     """
04:     button.py 
05:     
06:     This demonstration script creates a toplevel window containing
07:     several button widgets.
08:     
09:     June 14, 2005
10:     """
11:     
12:     
13:     import Tkinter as Tk
14:     import template as A
15:     
16:     
17:     class Button(Tk.Button):
18:         """ Buttons to change bg of frames """
19:         def __init__(self, master, obj, color_name, color_id):
20:             Tk.Button.__init__(self, master, text=color_name, width=15, command=self.command)
21:             self.obj = obj
22:             self.color_id = color_id
23:     
24:         def command(self):
25:             self.obj.demo_frame.config(bg=self.color_id)
26:             self.obj.demo_buttons.config(bg=self.color_id)
27:             
28:     
29:     class Demo(A.Demo):
30:         """a demo class """
31:         
32:         def __init__(self, cmain):
33:             A.Demo.__init__(self, cmain, __file__)
34:             self.ini_frame()
35:     
36:         def ini_demo_called(self):
37:             """ This method should be defined"""
38:             self.ini_demo_called_0()
39:             self.ini_frame()
40:     
41:         def ini_frame(self):
42:             self.demo_main_frame.master.title("Button Demonstration")
43:             self.demo_main_frame.master.geometry('+50+50')
44:             A.Label(self.demo_main_frame, text=
45:             "If you click on any of the four buttons below, " 
46:             "the background of the button area will change to the color indicated in the button."
47:             , width=35, wraplength='8c')
48:             for name, code in [('Deeppink', '#FF1493'), ('Cornflowerblue', '#6495ED'),
49:                                  ('Springgreen', '#00FF7F'), ('Gold', '#FFD700')]:
50:                 b = Button(self.demo_frame, self, name, code) 
51:                 b.pack(padx=10, pady=5)
52:     
53:     
54:     ##------------------------------------------------ 
55:     def demo(*av):
56:         """ function called by `index.py'"""
57:         d = Demo(False)
58:         d.demo_window.focus_set()
59:     
60:     if __name__ == '__main__':
61:         d = Demo(True)
62:         d.demo_main_frame.mainloop()
手順は以下の通りです。
  1. 26 行目を削除。
  2. 29--41 行目を削除し、次のコードを挿入します。
    01:     class Frame(Tk.Frame):
    02:         def __init__(self, master=None):
    03:             Tk.Frame.__init__(self, master)
    04:             self.demo_frame = Tk.Frame(self)
    05:             self.demo_frame.pack(side=Tk.BOTTOM, fill=Tk.BOTH, expand=1)
    06:     #もし、スクリプト中に self.demo_buttons が現れるようなら、次の2行も追加します。
    07:     #        self.demo_buttons = Tk.Frame(self.demo_frame)
    08:     #        self.demo_buttons.pack(Tk.BOTTOM)
    
  3. 44--47 行目を次のように変更します。 Label widget のオプションに font と justify を追加します。
    01:             label=Tk.Label(self, text=
    02:             "If you click on any of the four buttons below, " 
    03:             "the background of the button area will change to the color indicated in the button."
    04:             , width=35, wraplength='8c', font=('Helvetica', '14'), justify=Tk.LEFT)
    05:             label.pack()
    
  4. 55--62 行目を削除し、以下の行を挿入します。
    01:     if __name__ == '__main__':
    02:         a = Frame()
    03:         a.pack()
    04:         a.mainloop()
    
  5. スクリプト中の全ての self.demo_main_frameself に置き換えます。
変換したスクリプトを動かすと下図のような widget が現れます。

6. 終わりに

最後に、主な Tkinter の解説記事を挙げておきます。
  1. Tkinter reference: a GUI for Python, by J. W. Shipman (PDF): Web 上にある最もまとまっている文書。大変参考になった。
  2. An Introduction to Tkinter, by F. Lundh: これも良くまとまった文書。<1> の補完になる。
  3. Tkinter Wiki: Tkinter に関する情報源
  4. 日本麻酔科学会関西支部: Widget ごとの簡単な説明。
  5. Cafe de Paison: 日本語の入門サイト Tkinter のほかに wxPython, Qt などの情報有り。
  6. Python with Tkinter : PythonのTkinterでGUIするページ: 日本語の入門サイト
  7. Python/Tkinter の演習: 日本語のデモサイト、 アスキー出版、久野 靖著「入門 tcl/tk」の例題をPython/Tkinter に変換したもの。