手を動かさないと飽きるので。(笑)
というわけで、Gladeを起動してください。
TopLevelのウィンドウをクリックして、右側のプロパティから、シグナルを選択します。
たくさん並んでいるので、ちと紛らわしいかも知れませんが、GtkObjectのクリッカ(+)を押して、開いてみましょう。
destroyというのが見えると思います。
その脇にシグナルの名前、というのがありますので、そこでダブルクリックすると、シグナルの名前を入力できるようになります。
が、まあ、ドロップダウンで選択できるので、選択してしまいましょう。(笑)
こんな感じ。一応赤枠で括ってみました。
ここで選択した名前が重要です。
#ってほど重要でもないので、一番上のを選んでおきましょうか。
きちんと確定したら、保存してGladeは終了してしまいます。
次に設定したシグナルハンドラをプログラムに組み込みます。
NetBeansを起動しましょう。
self.wTree.add_from_file(os.path.dirname(os.path.abspath(__file__)) + "/"+self.gladefile) #Create our dictionay and connect it dic = { "on_TopLevel_destroy" : self.on_TopLevel_destroy } self.wTree.connect_signals(dic)
こんな感じになります。
Gladeで作ったファイルを読み込んだ直後くらいに、Pythonのディクショナリ形式の変数を作成し、GTKBuilderのメソッドである、connect_signalに渡して、メソッドとシグナルを結びつけるわけです。
on_TopLevel_destroyは、先程Gladeで設定したシグナルの名前、self.on_TopLevel_destroyは、これからこのクラスの中で宣言するメソッドになります。
この際、一気に、self.on_TopLevel_destroyも書いてしまいましょう。
def on_TopLevel_destroy(self, widget): #ウィンドウを閉じてアプリケーションを終了する gtk.main_quit()
単純に、gtk.main_quit()を呼んでいるだけですね。
これは、先に実行していたgtk.main()を終了させるためのメソッドになります。
もしも、終了時になんらかの処理を行う場合には、このメソッドに処理を組み込むことになりますね。
例えば、終了確認とか、設定値の保存とか。
まあ、今はまだ、なんもすることがないので、単純に終了するだけです。
シグナルに結び付けられるメソッドをシグナルハンドラと言ったりします。
#イベントハンドラとかな。
この場合は、☓ボタンを押される、というシグナル(イベント)をハンドリングするので、そういう呼ばれ方をしているわけですね。
この手のハンドラの定型的な書き方が上記の書き方になります。
MikunchAppクラスのメソッドなので、最初の引数(カッコの中身)は、必ずselfになります。
そういう決まりらしいので、これは仕方ないんです。(笑)
次のwidgetというのは、シグナルを起こしたウィジェット、この場合はTopLevelのウィンドウオブジェクトが渡されてきます。
シグナルが発生した場合には、そのシグナルを起こしたオブジェクトに対してのアクションを起こすことが多いので、引数として渡ってくるんですね。
ちなみに、引数ってなんだ、って話になりますが、また、あとで座学します。(笑)
起きるシグナル、引き金となるウィジェットによって、この引数が変わってきます、が、まあ今はそんなに気にしなくてもいいです。
気になるひとは、この辺見ときましょう。
全体像としては、こんな感じになります。
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys import commands import os import os.path import pygtk import gtk __author__="kaoru" __date__ ="$2010/08/28 13:42:04$" class MikunchApp: def __init__(self): #Set the Glade file self.gladefile = "mikunchu.ui" self.wTree = gtk.Builder() self.wTree.add_from_file(os.path.dirname(os.path.abspath(__file__)) + "/"+self.gladefile) #Create our dictionay and connect it dic = { "on_TopLevel_destroy" : self.on_TopLevel_destroy } self.wTree.connect_signals(dic) self.mainWindow = self.wTree.get_object ("TopLevel") self.mainWindow.show_all() def on_TopLevel_destroy(self, widget): #ウィンドウを閉じてアプリケーションを終了する gtk.main_quit() if __name__ == "__main__": MikunchApp() gtk.main()
これで、ウィンドウの☓ボタンを押したときに、プログラムが終了するようになります。
なんか、プログラムーって感じになってきましたね。(笑)
でも、たったこれだけしか書いてないのです。
#まあ、Glade使ってるから、なんだが。
同様に、ボタンを押した時のシグナルも記述することが出来ます。
単純に、ボタンを押したら終了する、って感じにだけ、しときましょうか?
そんじゃまあ、ふたたびGladeを起動してもらって。
手順はウィンドウの場合と同じです。今度はボタンをクリックして、GtkButtonのClickシグナルに名前を付ける、ってのが異なる点でしょうか。
こんな感じ。やっぱり赤枠を付けときました。
同様に、キャンセルボタンもやってしまいましょう。
それぞれのハンドラも含めた、全体像は以下のようになります。
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys import commands import os import os.path import pygtk import gtk __author__="kaoru" __date__ ="$2010/08/28 13:42:04$" class MikunchApp: def __init__(self): #Set the Glade file self.gladefile = "mikunchu.ui" self.wTree = gtk.Builder() self.wTree.add_from_file(os.path.dirname(os.path.abspath(__file__)) + "/"+self.gladefile) #Create our dictionay and connect it dic = { "on_btCansel_clicked" : self.on_btnCancel_clicked, "on_btOK_clicked" : self.on_btnOK_clicked, "on_TopLevel_destroy" : self.on_TopLevel_destroy } self.wTree.connect_signals(dic) self.mainWindow = self.wTree.get_object ("TopLevel") self.mainWindow.show_all() def on_TopLevel_destroy(self, widget): #ウィンドウを閉じてアプリケーションを終了する gtk.main_quit() def on_btnOK_clicked(self,widget): #ウィンドウを閉じてアプリケーションを終了する gtk.main_quit() def on_btnCancel_clicked(self,widget): #ウィンドウを閉じてアプリケーションを終了する gtk.main_quit() if __name__ == "__main__": MikunchApp() gtk.main()
dicの中身が増えて、それに対応するハンドラのメソッドが増えました。
これで、☓ボタンを押す、OKボタンを押す、キャンセルボタンを押す、のいずれかの操作により、プログラムが終了します。
とまあ、まじめくさって説明してみましたが、こんなの書いてしまえば、15分程度で済むようなところです。(笑)
問題は、ボタンを押されたら、何をするか、ってことなんですが、まあ、そこはもう少し先ってことにして、次はまた座学にしようかなーとか思ってますけど。
そもそも、シグナルってなんだよ、とか。
どういう仕組みで、そのシグナルがプログラムに飛んでくんだよ、みたいなところを軽く説明しつつ、メソッドの引数とかについても触れてみましょうかね。
まあ、何度も書いてますが、身構えるようなもんじゃありません。
知らないから、難しいだけで、解ってしまえば単純なものです。
プログラムなんて、そんな難しいもんじゃないんですよ。
GUIだって、ツールを使えば、こんな簡単に実装出来てしまうんですから。(笑)
0 件のコメント:
コメントを投稿