Tkinter モジュール (“Tk インタフェース”) は、 Tk GUI ツールキットに対する標準の Python インタフェースです。 Tk と Tkinter はほとんどの Unix プラットフォームの他、 Windows システム上でも利用できます。 (Tk 自体は Python の一部ではありません。 Tk は ActiveState で保守されています。)
参考
ほとんどの場合、本当に必要となるのは Tkinter モジュールだけですが、他にもいくつかの追加モジュールを利用できます。 Tk インタフェース自体は _tkinter と言う名前のバイナリモジュール内にあります。このモジュールに入っているのは Tk への低水準のインタフェースであり、アプリケーションプログラマが直接使ってはなりません。 _tkinter は通常共有ライブラリ (や DLL) になっていますが、 Python インタプリタに静的にリンクされていることもあります。
Tk インタフェースモジュールの他にも、 Tkinter には Python モジュールが数多く入っています。最も重要なモジュールは、 Tkinter 自体と Tkconstants と呼ばれるモジュールの二つです。前者は自動的に後者を import するので、以下のように一方のモジュールを import するだけで Tkinter を使えるようになります:
import Tkinter
あるいは、よく使うやり方で:
from Tkinter import *
のようにします。
Tk クラスは引数なしでインスタンス化します。これは Tk のトップレベルウィジェットを生成します。通常、トップレベルウィジェットはアプリケーションのメインウィンドウになります。それぞれのインスタンスごとに固有の Tcl インタプリタが関連づけられます。
バージョン 2.4 で変更: useTk パラメタが追加されました.
Tcl() はファクトリ関数で、 Tk クラスで生成するオブジェクトとよく似たオブジェクトを生成します。ただし Tk サブシステムを初期化しません。この関数は、余分なトップレベルウィンドウを作る必要がなかったり、 (X サーバを持たない Unix/Linux システムなどのように) 作成できない環境において Tcl インタプリタを駆動したい場合に便利です。 Tcl() で生成したオブジェクトに対して loadtk() メソッドを呼び出せば、トップレベルウィンドウを作成 (して、Tk サブシステムを初期化) します。
バージョン 2.4 で追加.
Tk をサポートしているモジュールには、他にも以下のようなモジュールがあります:
これらも Python 3.0 で改名されました。新たな tkinter パッケージのサブモジュールになったのです。
この節は、 Tk や Tkinter を全て網羅したチュートリアルを目指しているわけではありません。むしろ、Tkinter のシステムを学ぶ上での指針を示すための、その場しのぎ的なマニュアルです。
謝辞:
この節は二つの部分で構成されています: 前半では、背景となることがらを (大雑把に) 網羅しています。後半は、キーボードの横に置けるような手軽なリファレンスになっています。
「ホゲホゲ (blah) するにはどうしたらよいですか」という形の問いに答えようと思うなら、まず Tk で「ホゲホゲ」する方法を調べてから、このドキュメントに戻ってきてその方法に対応する Tkinter の関数呼び出しに変換するのが多くの場合最善の方法になります。 Python プログラマが Tk ドキュメンテーションを見れば、たいてい正しい Python コマンドの見当をつけられます。従って、 Tkinter を使うには Tk についてほんの少しだけ知っていればよいということになります。このドキュメントではその役割を果たせないので、次善の策として、すでにある最良のドキュメントについていくつかヒントを示しておくことにしましょう:
参考
from Tkinter import *
class Application(Frame):
def say_hi(self):
print "hi there, everyone!"
def createWidgets(self):
self.QUIT = Button(self)
self.QUIT["text"] = "QUIT"
self.QUIT["fg"] = "red"
self.QUIT["command"] = self.quit
self.QUIT.pack({"side": "left"})
self.hi_there = Button(self)
self.hi_there["text"] = "Hello",
self.hi_there["command"] = self.say_hi
self.hi_there.pack({"side": "left"})
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
self.createWidgets()
root = Tk()
app = Application(master=root)
app.mainloop()
root.destroy()
クラス階層は複雑に見えますが、実際にプログラムを書く際には、アプリケーションプログラマはほとんど常にクラス階層の最底辺にあるクラスしか参照しません。
注意:
このリファレンス資料を活用するには、Tk の短いプログラムを読んだり、 Tk コマンドの様々な側面を知っておく必要がままあるでしょう。 (下の説明の Tkinter 版は、 基本的な Tk プログラムと Tkinter との対応関係 節を参照してください。)
Tk スクリプトは Tcl プログラムです。全ての Tcl プログラムに同じく、 Tk スクリプトはトークンをスペースで区切って並べます。 Tk ウィジェットとは、ウィジェットの クラス 、ウィジェットの設定を行う オプション 、そしてウィジェットに役立つことをさせる アクション をあわせたものに過ぎません。
Tk でウィジェットを作るには、常に次のような形式のコマンドを使います:
classCommand newPathname options
以下に例を示します:
button .fred -fg red -text "hi there"
^ ^ \_____________________/
| | |
class new options
command widget (-opt val -opt val ...)
ウィジェットを作成すると、ウィジェットへのパス名は新しいコマンドになります。この新たな widget command は、プログラマが新たに作成したウィジェットに action を実行させる際のハンドル (handle) になります。C では someAction(fred, someOptions) と表し、 C++ では fred.someAction(someOptions) と表すでしょう。Tkでは:
.fred someAction someOptions
のようにします。オブジェクト名 .fred はドットから始まっているので注意してください。
読者の想像の通り、 someAction に指定できる値はウィジェットのクラスに依存しています: fred がボタンなら .fred disable はうまくいきます (fred はグレーになります) が、fred がラベルならうまくいきません (Tkではラベルの無効化をサポートしていないからです)。
someOptions に指定できる値はアクションの内容に依存しています。 disable のようなアクションは引数を必要としませんが、テキストエントリボックスの delete コマンドのようなアクションにはテキストを削除する範囲を指定するための引数が必要になります。
Tkのクラスコマンドは、Tkinterのクラスコンストラクタに対応しています。
button .fred =====> fred = Button()
オブジェクトの親 (master) は、オブジェクトの作成時に指定した新たな名前から非明示的に決定されます。Tkinter では親を明示的に指定します。
button .panel.fred =====> fred = Button(panel)
Tk の設定オプションは、ハイフンをつけたタグと値の組からなるリストで指定します。Tkinter では、オプションはキーワード引数にしてインスタンスのコンストラクタに指定したり、 config() にキーワード引数を指定して呼び出したり、インデクス指定を使ってインスタンスに代入したりして設定します。オプションの設定については オプションの設定 節を参照してください。
button .fred -fg red =====> fred = Button(panel, fg = "red")
.fred configure -fg red =====> fred["fg"] = red
OR ==> fred.config(fg = "red")
Tk でウィジェットにアクションを実行させるには、ウィジェット名をコマンドにして、その後にアクション名を続け、必要に応じて引数 (オプション) を続けます。 Tkinter では、クラスインスタンスのメソッドを呼び出して、ウィジェットのアクションを呼び出します。あるウィジェットがどんなアクション (メソッド) を実行できるかは、 Tkinter.py モジュール内にリストされています。
.fred invoke =====> fred.invoke()
Tk でウィジェットを packer (ジオメトリマネジャ) に渡すには、 pack コマンドをオプション引数付きで呼び出します。 Tkinter では Pack クラスがこの機能すべてを握っていて、様々な pack の形式がメソッドとして実装されています。 Tkinter のウィジェットは全て Packer からサブクラス化されているため、pack 操作にまつわる全てのメソッドを継承しています。 Form ジオメトリマネジャに関する詳しい情報については Tix モジュールのドキュメントを参照してください。
pack .fred -side left =====> fred.pack(side = "left")
上から下に、呼び出しの階層構造を説明してゆきます:
オプションは、色やウィジェットの境界線幅などを制御します。オプションの設定には三通りの方法があります:
fred = Button(self, fg = "red", bg = "blue")
fred["fg"] = "red"
fred["bg"] = "blue"
fred.config(fg = "red", bg = "blue")
オプションとその振る舞いに関する詳細な説明は、該当するウィジェットの Tk の man マニュアルを参照してください。
man マニュアルには、各ウィジェットの “STANDARD OPTIONS (標準オプション)” と “WIDGET SPECIFIC OPTIONS (ウィジェット固有のオプション)” がリストされていることに注意しましょう。前者は多くのウィジェットに共通のオプションのリストで、後者は特定のウィジェットに特有のオプションです。標準オプションの説明は man マニュアルの options(3) にあります。
このドキュメントでは、標準オプションとウィジェット固有のオプションを区別していません。オプションによっては、ある種のウィジェットに適用できません。あるウィジェットがあるオプションに対応しているかどうかは、ウィジェットのクラスによります。例えばボタンには command オプションがありますが、ラベルにはありません。
あるウィジェットがどんなオプションをサポートしているかは、ウィジェットの man マニュアルにリストされています。また、実行時にウィジェットの config() メソッドを引数なしで呼び出したり、 keys() メソッドを呼び出したりして問い合わせることもできます。メソッド呼び出しを行うと辞書型の値を返します。この辞書は、オプションの名前がキー (例えば 'relief') になっていて、値が 5 要素のタプルになっています。
bg のように、いくつかのオプションはより長い名前を持つ共通のオプションに対する同義語になっています (bg は “background” を短縮したものです)。短縮形のオプション名を config() に渡すと、 5 要素ではなく 2 要素のタプルを返します。このタプルには、同義語の名前と「本当の」オプション名が入っています (例えば ('bg', 'background'))。
インデックス | 意味 | 例 |
---|---|---|
0 | オプション名 | 'relief' |
1 | データベース検索用のオプション名 | 'relief' |
2 | データベース検索用のオプションクラス | 'Relief' |
3 | デフォルト値 | 'raised' |
4 | 現在の値 | 'groove' |
例:
>>> print fred.config()
{'relief' : ('relief', 'relief', 'Relief', 'raised', 'groove')}
もちろん、実際に出力される辞書には利用可能なオプションが全て表示されます。上の表示例は単なる例にすぎません。
packer は Tk のジオメトリ管理メカニズムの一つです。ジオメトリマネジャは、複数のウィジェットの位置を、それぞれのウィジェットを含むコンテナ - 共通の マスタ (master) からの相対で指定するために使います。やや扱いにくい placer (あまり使われないのでここでは取り上げません) と違い、packer は定性的な関係を表す指定子 - 上 (above) 、 〜の左 (to the left of) 、 引き延ばし (filling) など - を受け取り、厳密な配置座標の決定を全て行ってくれます。
どんな マスタ ウィジェットでも、大きさは内部の “スレイブ (slave) ウィジェット” の大きさで決まります。 packer は、スレイブウィジェットを pack 先のマスタウィジェット中のどこに配置するかを制御するために使われます。望みのレイアウトを達成するには、ウィジェットをフレームにパックし、そのフレームをまた別のフレームにパックできます。さらに、一度パックを行うと、それ以後の設定変更に合わせて動的に並べ方を調整します。
ジオメトリマネジャがウィジェットのジオメトリを確定するまで、ウィジェットは表示されないので注意してください。初心者のころにはよくジオメトリの確定を忘れてしまい、ウィジェットを生成したのに何も表示されず驚くことになります。ウィジェットは、(例えば packer の pack() メソッドを適用して) ジオメトリを確定した後で初めて表示されます。
pack() メソッドは、キーワード引数つきで呼び出せます。キーワード引数は、ウィジェットをコンテナ内のどこに表示するか、メインのアプリケーションウィンドウをリサイズしたときにウィジェットがどう振舞うかを制御します。以下に例を示します:
fred.pack() # デフォルトでは、side = "top"
fred.pack(side = "left")
fred.pack(expand = 1)
packer と packer の取りえるオプションについての詳細は、man マニュアルや John Ousterhout の本の183ページを参照してください。
ウィジェットによっては、(テキスト入力ウィジェットのように) 特殊なオプションを使って、現在設定されている値をアプリケーション内の変数に直接関連付けできます。このようなオプションには variable, textvariable, onvalue, offvalue および value があります。この関連付けは双方向に働きます: 変数の値が何らかの理由で変更されると、関連付けされているウィジェットも更新され、新しい値を反映します。
残念ながら、現在の Tkinter の実装では、 variable や textvariable オプションでは任意の Python の値をウィジェットに渡せません。この関連付け機能がうまく働くのは、 Tkinter モジュール内で Variable というクラスからサブクラス化されている変数によるオプションだけです。
Variable には、 StringVar, IntVar, DoubleVar, BooleanVar といった便利なサブクラスがすでにすでに数多く定義されています。こうした変数の現在の値を読み出したければ、 get() メソッドを呼び出します。また、値を変更したければ set() メソッドを呼び出します。このプロトコルに従っている限り、それ以上なにも手を加えなくてもウィジェットは常に現在値に追従します。
例えば:
class App(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
self.entrythingy = Entry()
self.entrythingy.pack()
# アプリケーション変数です
self.contents = StringVar()
# 変数の値を設定します
self.contents.set("this is a variable")
# エントリウィジェットに変数の値を監視させます
self.entrythingy["textvariable"] = self.contents
# ユーザがリターンキーを押した時にコールバックを呼び出させます
# これで、このプログラムは、ユーザがリターンキーを押すと
# アプリケーション変数の値を出力するようになります。
self.entrythingy.bind('<Key-Return>',
self.print_contents)
def print_contents(self, event):
print "hi. contents of entry is now ---->", \
self.contents.get()
Tk には、ウィンドウマネジャとやり取りするための wm というユーティリティコマンドがあります。 wm コマンドにオプションを指定すると、タイトルや配置、アイコンビットマップなどを操作できます。 Tkinter では、こうしたコマンドは Wm クラスのメソッドとして実装されています。トップレベルウィジェットは Wm クラスからサブクラス化されているので、 Wm のメソッドを直接呼び出せます。
あるウィジェットの入っているトップレベルウィンドウを取得したい場合、大抵は単にウィジェットのマスタを参照するだけですみます。とはいえ、ウィジェットがフレーム内にパックされている場合、マスタはトップレベルウィンドウではありません。任意のウィジェットの入っているトップレベルウィンドウを知りたければ _root() メソッドを呼び出してください。このメソッドはアンダースコアがついていますが、これはこの関数が Tkinter の実装の一部であり、Tk の機能に対するインタフェースではないことを示しています。
以下に典型的な使い方の例をいくつか挙げます:
from Tkinter import *
class App(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
# アプリケーションを作成します
myapp = App()
#
# ウィンドウマネジャクラスのメソッドを呼び出します。
#
myapp.master.title("My Do-Nothing Application")
myapp.master.maxsize(1000, 400)
# プログラムを開始します
myapp.mainloop()
これは引数を取らない Python 関数ならどれでも構いません。例えば:
def print_it():
print "hi there"
fred["command"] = print_it
ウィジェットコマンドからの bind メソッドによって、あるイベントを待つことと、そのイベント型が起きたときにコールバック関数を呼び出すことができるようになります。 bind メソッドの形式は:
def bind(self, sequence, func, add=''):
ここでは:
例えば:
def turnRed(self, event):
event.widget["activeforeground"] = "red"
self.button.bind("<Enter>", self.turnRed)
イベントのウィジェットフィールドが turnRed() コールバック内でどのようにアクセスされているかに注意してください。このフィールドは X イベントを捕らえるウィジェットを含んでいます。以下の表はあなたがアクセスできる他のイベントフィールドとそれらの Tk での表現方法の一覧です。Tk man ページを参照するときに役に立つでしょう。
Tk Tkinterイベントフィールド Tk Tkinterイベントフィールド
-- ------------------------- -- -------------------------
%f focus %A char
%h height %E send_event
%k keycode %K keysym
%s state %N keysym_num
%t time %T type
%w width %W widget
%x x %X x_root
%y y %Y y_root
たくさんのウィジェットが渡される”index”パラメータを必要とします。これらはテキストウィジェットでの特定の場所や、エントリウィジェットでの特定の文字、あるいは、メニューウィジェットでの特定のメニュー項目を指定するために使われます。
エントリウィジェットは表示されているテキスト内の文字位置を参照するオプションを持っています。テキストウィジェットにおけるこれらの特別な位置にアクセスするために、これらの Tkinter 関数を使うことができます:
メニューに対するいくつかのオプションとメソッドは特定のメニュー項目を操作します。メニューインデックスはオプションまたはパラメータのために必要とされるときはいつでも、以下のものを渡すことができます:
Bitmap/Pixelmap 画像を Tkinter.Image のサブクラスを使って作ることができます:
画像のどちらの型でも file または data オプションを使って作られます (その上、他のオプションも利用できます)。
image オプションがウィジェットにサポートされるところならどこでも、画像オブジェクトを使うことができます(例えば、ラベル、ボタン、メニュー)。これらの場合では、Tk は画像への参照を保持しないでしょう。画像オブジェクトへの最後の Python の参照が削除されたときに、おまけに画像データが削除されます。そして、どこで画像が使われていようとも、Tk は空の箱を表示します。