3265558 ランダム
 HOME | DIARY | PROFILE 【フォローする】 【ログイン】

傀儡師の館.Python

傀儡師の館.Python

【毎日開催】
15記事にいいね!で1ポイント
10秒滞在
いいね! --/--
おめでとうございます!
ミッションを達成しました。
※「ポイントを獲得する」ボタンを押すと広告が表示されます。
x

PR

Recent Posts

Calendar

Keyword Search

▼キーワード検索

Category

Archives

2023.11
2023.10
2023.09
2023.08
2023.07

Freepage List

Profile

kugutsushi

kugutsushi

Free Space

設定されていません。
2010.10.06
XML
カテゴリ:Python
wPython.org の Getting Started をサカナに第五弾。これまでテキストコントロール (wx.TextCtrl) に文字を表示し、文字色や背景色を変更したり、表示フォントを変更してみた。そして、メニューやステータスバーを付けるところまでやった。今度は、メニューを選択したときに何かの処理が行われるようなところを作ってみる。つまり、話題としては、イベントハンドリング(Event handling) の箇所。



そういえば、前回、Standard event identifiersで、wx.ID_xxx のドキュメントがあるのを気づかずに通り越していた。wxID_LOWEST = 4999、 wxID_HIGHEST = 5999 なので、この範囲はユーザーが直接使うのは避けましょうということも書いてあった。さらにメニューを作るときには、Stock items を見るとよさそう。

メニューとイベントとイベントハンドラーを結びつける



まずは、下記を確認。

メインループ(Main loop)とは、イベント駆動型GUIなどの機能を持つアプリケーションで典型的な設計手法。イベントループ(Event loop)とも呼ばれる。常に実行されているループを持ち、ユーザーイベントの有無をループする度に確認し、それイベントを処理する。何らかの方法でイベントを処理すると、制御は前述のループに戻り、次にイベントが発生するまでループを回り続ける。このようなプログラムではループが最上位の制御構造となっており、そのため「メイン」と名づけられている。




ということで、wx
wxPython で作ったプログラムを実行するとき、一番最後に app.MainLoop() としているのは、プログラムがイベントループの状態にさせるため。そうすると、プログラムは、マウスやキーボード、あるいはタイマーなどのイベントを捕まえて、それによって何かのアクションが引き起こされるようになる。wxPython のイベントには、wxPython のイベントの一覧 のようなものがある。これは、

import wx

for x in dir(wx):
if x.startswith('EVT_'):
print x


のようにして参照することもできる。

たとえば、メニューを選択したときには、wx.EVT_MENU
が発生する。これを拾って、何かの処理を起動してやるという処理を書く必要がある。このイベントと、そのイベントに対応する処理(イベントハンドラー) を結び付けてあげるのに Bind メソッドを使う。

Bind の構文は、

def Bind(self, event, handler, source=None, id=wxID_ANY, id2=wxID_ANY):

例:
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Bind(wx.EVT_BUTTON, self.OnButtonClick, theButton)
self.Bind(wx.EVT_MENU, self.OnExit, id=wx.ID_EXIT)


たとえば、次のようになる。

menuItem = filemenu.Append(wx.ID_ABOUT, "&About"," このプログラムの情報")
self.Bind(wx.EVT_MENU, self.OnAbout, menuItem)


Bind の第一引数は、イベントの種類。メニュー操作を扱うためのイベントなので wx.EVT_MENU が指定されている。次に指定されているのが、イベントハンドラー。このメソッドでメニューが選択されたときの処理メソッドを指定する(これは別途作成する)。3つめの引数がソースで、ここではメニューアイテムオブジェクト。ここで指定されたメニューアイテムが選択されると EVT_MENU のイベント発生し、イベントハンドラーの self.OnAbout に渡され、そこでなんらかの処理をする。なので、イベントハンドラーのメソッドには、このイベントを引数として受け取れるようにする必要があるので def foo(self, event) のようになる。

前回のコードでは、

filemenu.Append(wx.ID_ABOUT, "&About"," このプログラムの情報")


としていたが、各メニューアイテムオブジェクト(ソース)を格納する変数を用意しなければならないので、

menuItem = filemenu.Append(wx.ID_ABOUT, "&About"," このプログラムの情報")


のようにするところに注意。そうしたうえで、バインドする。

self.Bind(wx.EVT_MENU, self.OnAbout, menuItem)


さらに、MyFlame クラスの中で、

def OnAbout(self, event):
# イベントを受け取って、何かを処理する
print "Select About”


のようになる。

ちなみに、wx.EVT_MENU や wx.EVT_BUTTON などのイベントは、すべて wx.Event のサブクラス。また、あるメソッドがイベントを受け取ったときに処理をせずに、イベントループに戻すには、event.Skip() を呼び出せばよい。

たとえば、

def OnButtonClick(self, event):
if (some_condition):
do_something()
else:
event.Skip()


のように使う。

もし、ボタンがクリックされても、some_condition が False であれば、このメソッドでは処理を行わないことになる。もし、このスキップを行わない場合、メソッド終了とともに、このイベントの扱いは完了してしまう。けれども、event_skip() としておくと、他のメソッドでこのイベントを扱うように設定されてれば、引き続き、そのメソッドで処理ができる。

ということで、とりあえず、各メニューが選択されたら、コンソール上に "Select 選択されたメニュー" を表示するようにしてみた。
コードが少し長くなるので、次のエントリに続く。





無料アクセス解析






お気に入りの記事を「いいね!」で応援しよう

Last updated  2015.03.08 17:09:14
コメント(0) | コメントを書く



© Rakuten Group, Inc.