■ 概要
PyGTK ライブラリを使い、GUI ソフトウェア を簡単に作成する方法を紹介いたします。
PyGTK は、グラフィカルなソフトウェアの作成を支援するライブラリ GTK を Python 言語から利用可能にするライブラリです。
主なドキュメントに、 チュートリアル と ライブラリリファレンス があります。
(PyGTK を利用して作成されたソフトウェアの例)
Python は、スクリプト言語の一種で、シンプルな文法が特徴です。
Python は、充実した 標準ライブラリ を備えており、さらに、多数の 拡張ライブラリ が存在します。
また、 日本語チュートリアル をはじめ、 数多くのドキュメント が存在します。
Linux ディストリビューションの多くに標準でインストールされており、 管理ツールの中には Python で書かれたものが多数あります。
Python を利用して、 さまざまソフトウェア が構築されています。
PyGTK では、GUI 部品 のことを ウィジェット(Widget) と呼びます。
複雑なデザインのウィンドウも、ウィジェットの組み合わせによって作られています。
(PyGTK に収録されているウィジェットの例)
PyGTK には、多数のウィジェットが用意されています。
スクリーンショット | ウィジェット | PyGTK クラス名 | 備考 |
---|---|---|---|
(省略) | ウィンドウ | gtk.Window | GUI のベースになるウィンドウです。 各ウィジェットはこの中に収納されます。 |
ボタン | gtk.Button | 押下可能なボタンです。 | |
ラジオボタン | gtk.RadioButton | 複数の選択肢から選ぶためのボタンです。 複数のラジオボタンをグループ化して使います。 |
|
チェック ボックス |
gtk.CheckButton | 設定の有効/無効を切り替えるボタンです。 | |
スピンボタン | gtk.SpinButton | 数値を増減させるためのボタンです。 | |
ドロップダウン リスト |
gtk.ComboBox | 複数の選択肢から選ぶためのボックスです。 複数の値をあらかじめ登録して利用します。 |
|
メニュー | gtk.Menubar | ウィンドウの上部に表示されるメニューです。 あらかじめメニューアイテムを登録して 利用します。 |
|
タブ | gtk.Notebook | 複数のページを選択するためのタブです。 各ページをあらかじめ登録して利用します。 後からページを追加/削除することも可能です。 |
|
ラベル | gtk.Label | テキストを表示します。 数行に渡るテキストも表示可能です。 |
|
画像表示 | gtk.Image | 画像を表示します。 画像データは別途割り当てる必要があります。 画像データは後から差し替え可能です。 |
|
スクロールバー | gtk.HScrollbar gtk.VScrollbar |
(PyGTK で用意されているウィジェットの一例です)
これらのウィジェットを組み合わせることにより、 いろいろなデザインの GUI を作成することができます。
※各ウィジェットの詳細は Reference に、チュートリアルは Tutorial にあります。
PyGTK では、複数のウィジェットを並べるのに「パック」という考え方をします。
GUI アプリケーションを作成する時、あなたはウィンドウ上にウィジェットを 2個以上配置したいと思うだろう。 私たちの最初の「Hello, world」アプリは1つだけのウィジェットを単純に gtk.Container クラスの add() メソッドでウィンドウ上に "pack" しただけだった。 あなたがウィンドウ上に2個以上のウィジェットを配置したい時、 あなたはどのようにしてウィジェットの配置をコントロールすればよいのだろう? その答えは「packing」だ。 たいていの「packing」は、Boxを作ることによってなされる。 この「Box」は透明なコンテナで、水平方向にウィジェットを並べる HBox (Horizontal Box) と、 垂直方向にウィジェットを並べる VBox(Vertical Box) とがある。 HBox を用いてパッキングする時は、ウィジェットは左から右、または右から左に 並べられる(関数の呼び出す順番に依存する)。 VBox を用いてパッキングする時は、ウィジェットは上から下、または下から上に 並べられる(関数の呼び出す順番に依存する)。 Box は入れ子にすることができる。(VBoxの中にHBoxを入れる、など)
「 PyGTK 2.0 Tutorial 」 ( Chapter 4. Packing Widget ) より引用
(先ほどのソフトウェアのウィジェット配置構成例)
GTK では、ボタンクリックなどの操作が行われた時に シグナル(signal) が発生します。
(ウィジェットが操作されると、それぞれ対応するシグナルが発生します)
「シグナルが発生した時になにをするか」をあらかじめ設定しておくことで、 ウィジェットに対して操作が行われた時の振る舞いを定義することができます。
具体的には、シグナルに対するシグナルハンドラ(コールバック関数)を用意してやり、 ウィジェットの connect()関数、または connect_object() 関数に渡します。
シグナルハンドラとしてコールバック関数を登録すると、シグナル発生時にその関数が呼ばれます。同じシグナルに対し、複数のシグナルハンドラを登録することも可能です。
connect() 関数呼び出しは、次の形式をとります:
handler_id = object.connect(name, func, func_data) # name: シグナル名 (文字列) # func: コールバック関数名 (関数オブジェクト) # func_data: 任意のデータ。コールバック時に func に渡される (オプション)
2番目の引数で渡される コールバック関数 は、一般に次の形を取ります。
def callback_func(widget, callback_data)
もし、コールバック関数がオブジェクトのメソッドなら、一般に次の形を取ります。
def callback_meth(self, widget, callback_data)
ここで、 self は、メソッドが呼ばれたオブジェクトのインスタンスです。
たとえば、 gtk.Button ウィジェットの clicked シグナルを捕捉したい時には、
handler_id = button.connect("clicked", button_clicked)
を実行します。
注意: ここまでに示したコールバック関数の形式は、あくまで一般的なものです。 ウィジェットによっては、(追加の情報を渡すために) 違う引数リストを持ちます。 たとえば、gtk.Widget の "size-allocate" シグナルのハンドラは、 次の引数リストを取る必要があります。 def callback_func(widget, allocation, callback_data) ※ allocation は gtk.gdk.Rectangle オブジェクトで、 新たにウィジェットに割り当てられた領域のサイズを表します。
PyGTK 版 Helloworld アプリケーションのサンプルです。
起動直後の状態
「Hello, World!!」ボタンを押すとラベルが変化
「Good night, World!!」ボタンを押すとラベルが変化
(ソースコード)
#!/usr/bin/env python # -*- coding:UTF-8 -*- # PyGTK モジュールをインポート import pygtk pygtk.require('2.0') import gtk class HelloWorld: def __init__(self): # Hello World ウィンドウを作成 self.window = gtk.Window() self.window.set_title('Hello, world!') self.window.connect('destroy_event', self.end_application) self.window.connect('delete_event', self.end_application) # ボタンが押されるごとに表示が変わるラベルを作成 self.label_show = gtk.Label() self.label_show.set_markup('<big><b>Zzz...</b></big>') # 押すと 「Hello, World!!」と表示するボタンを作成 self.button_hw = gtk.Button() self.button_hw.set_label('Hello, World!!') self.button_hw.connect('clicked', self.set_hw_txt) # 押すと 「Good night, World!!」と表示するボタンを作成 self.button_gn = gtk.Button() self.button_gn.set_label('Good night, World!!') self.button_gn.connect('clicked', self.set_gn_txt) # 押すとアプリケーションを終了するボタンを作成 self.button_quit = gtk.Button() self.button_quit.set_label('Quit') self.button_quit.connect('clicked', self.end_application) # ラベルとボタンを VBox にパック self.vbox = gtk.VBox() self.vbox.add(self.label_show) self.vbox.add(self.button_hw) self.vbox.add(self.button_gn) self.vbox.add(self.button_quit) # VBox をウィンドウに格納 self.window.add(self.vbox) # ウィンドウ、および配下の全ウィジェットを表示 self.window.show_all() def set_hw_txt(self, widget, data=None): #「Hello, World!!」ボタン用コールバック関数 # ラベルに「Hello, World!!」文字列をセット self.label_show.set_markup("<big><b>Hello, World!!</b></big>") def set_gn_txt(self, widget, data=None): #「Good night, World!!」ボタン用コールバック関数 # ラベルに「Good night, World!!」文字列をセット self.label_show.set_markup("<big><b>Good night, World!!</b></big>") def end_application(self, widget, data=None): # 「Quit」ボタン用コールバック関数 # アプリケーションを終了 gtk.main_quit() return False def main(): hw = HelloWorld() gtk.main() if __name__ == '__main__': main()