pygtkで遊ぼう(18) GObjectのサブクラスを作ってみる(その2)

昨日はGObjectのサブクラスを作って、独自のプロパティを持たせまました。

今日は、GObjectのサブクラスを作って、独自のシグナルを持たせてみます。
独自のシグナルを持たせると、既存のPyGTKのウィジェットなどと同様に、

obj.connect('signal-name', signal-handler)

といった感じで「connect」することで、自作のGObjectサブクラスからコールバックを受けることができるようになります。


実際のスクリプトは以下のような感じになります。

# -*- coding: utf-8 -*-

import sys
import pygtk
if sys.platform != 'win32':
    pygtk.require('2.0')

import gobject

#
#
class SubGObject(gobject.GObject):
    '''
    GObjectのサブクラス実験クラス
    '''
    # シグナルに感する設定
    __gsignals__ = {
        'signal-no-args': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
        'signal-two-args': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT, gobject.TYPE_INT)),
        }
    
    def __init__(self):
        '''
        初期化
        '''
        gobject.GObject.__init__(self)

    def emit_custom_signal(self):
        '''
        シグナルを発生させるためのテスト用メソッド
        '''
        self.emit('signal-no-args')
        self.emit('signal-two-args', 100, 200)
    
gobject.type_register(SubGObject)

#
#
if __name__ == '__main__':
    def cb_no_args(obj):
        print obj

    def cb_two_args(obj, arg1, arg2):
        print obj
        print arg1
        print arg2
    
    obj = SubGObject()
    obj.connect('signal-no-args', cb_no_args)
    obj.connect('signal-two-args', cb_two_args)

    obj.emit_custom_signal()

要点としては、

(1) トップレベルの変数として__gsignals__という辞書を追加し、シグナルの情報を記述する。
    辞書は、
      ・キー : シグナル名文字列
      ・値   : タプル(シグナルフラグ, 戻り値の型、引数型のタプル)

(2) emit(シグナル名文字列, 引数1, ....引数N)を呼び出し、シグナルを発生させる。

といったところです。

あと、上記のスクリプトには書かれていませんが、次のようなオプションもあります。

・シグナル名の最初にdo_を付加した関数を作成しておくと、シグナルが発生し、コールバックが呼び出されるたびに、
 そのdo_関数も呼び出される。
 例えば、上記のスクリプトのケースだと、do_signal_no_args()とかdo_signal_two_args()という関数を作成しておけばよい。

詳しい説明は、昨日も書きましたが以下のサイトにわかりやすく説明されています。
http://www.sicem.biz/personal/lgs/docs/docs/gobject-python/gobject-tutorial.html