Linuxmaniaトップ活用ガイドPyGTK を使ってみよう その1(Pyhton入門)

Linuxmania:活用ガイド


■ PyGTK を使ってみよう その1(Pyhton入門)(Fedora,CentOS,Ubuntu)


■ 概要
PyGTK ライブラリを使い、GUI ソフトウェア を簡単に作成する方法を紹介いたします。



1. PyGTK とは?


PyGTK は、グラフィカルなソフトウェアの作成を支援するライブラリ GTK を Python 言語から利用可能にするライブラリです。


主なドキュメントに、 チュートリアルライブラリリファレンス があります。


image/howto_pygtk/howto_pygtk-1-1.png

(PyGTK を利用して作成されたソフトウェアの例)


2. Python 言語 とは?


  Python は、スクリプト言語の一種で、シンプルな文法が特徴です。


  Python は、充実した 標準ライブラリ を備えており、さらに、多数の 拡張ライブラリ が存在します。


  また、 日本語チュートリアル をはじめ、 数多くのドキュメント が存在します。


 Linux ディストリビューションの多くに標準でインストールされており、 管理ツールの中には Python で書かれたものが多数あります。


  Python を利用して、 さまざまソフトウェア が構築されています。


3. PyGTK の GUI 構成方法


PyGTK では、GUI 部品 のことを ウィジェット(Widget) と呼びます。


複雑なデザインのウィンドウも、ウィジェットの組み合わせによって作られています。


image/howto_pygtk/howto_pygtk-3-1.png

(PyGTK に収録されているウィジェットの例)


3.1. ウィジェットの種類


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 にあります。


3.2. ウィジェットの配置方法


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 ) より引用


image/howto_pygtk/howto_pygtk-3-2.png

(先ほどのソフトウェアのウィジェット配置構成例)


4. GTK のシグナルの仕組み


GTK では、ボタンクリックなどの操作が行われた時に シグナル(signal) が発生します。


image/howto_pygtk/howto_pygtk-4-1.png

(ウィジェットが操作されると、それぞれ対応するシグナルが発生します)


「シグナルが発生した時になにをするか」をあらかじめ設定しておくことで、 ウィジェットに対して操作が行われた時の振る舞いを定義することができます。


具体的には、シグナルに対するシグナルハンドラ(コールバック関数)を用意してやり、 ウィジェットの connect()関数、または connect_object() 関数に渡します。


image/howto_pygtk/howto_pygtk-4-2.png

シグナルハンドラとしてコールバック関数を登録すると、シグナル発生時にその関数が呼ばれます。同じシグナルに対し、複数のシグナルハンドラを登録することも可能です。


connect() 関数呼び出しは、次の形式をとります:


handler_id = object.connect(name, func, func_data)
# name:      シグナル名 (文字列)
# func:      コールバック関数名 (関数オブジェクト)
# func_data: 任意のデータ。コールバック時に func に渡される (オプション)

object は シグナルを発する gtk.Widget のインスタンスです。
1番目の引数 name は、キャッチしたいシグナル名を文字列で指定します。
2番目の引数 func は、シグナルが発生した時に呼ばれるコールバック関数です。
3番目の引数 func_data は、コールバック関数呼び出しに渡されるデータです。
返り値 handler_id は、シグナルハンドラを解除またはブロックしたい時に利用します。

2番目の引数で渡される コールバック関数 は、一般に次の形を取ります。


def callback_func(widget, callback_data)

1番目の引数 widget では、シグナルを発したウィジェットへの参照が渡されます。
2番目の引数 callback_data は、connect() 関数呼び出し時に設定したデータが渡されます。

もし、コールバック関数がオブジェクトのメソッドなら、一般に次の形を取ります。


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 オブジェクトで、
  新たにウィジェットに割り当てられた領域のサイズを表します。

5. サンプルアプリケーション


PyGTK 版 Helloworld アプリケーションのサンプルです。


image/howto_pygtk/howto_pygtk-5-1.png

起動直後の状態


image/howto_pygtk/howto_pygtk-5-2.png

「Hello, World!!」ボタンを押すとラベルが変化


image/howto_pygtk/howto_pygtk-5-3.png

「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()

6. 参考文献



[作成日 2009/10/19]