要約すれば、
wx.PostEvent(dist, evt)
で、イベントを明示的に伝播できます、ということです。
追記
キーボードの入力というか、操作を受け付けたい時は、
wxPython(Phoenix) キーボード操作は、wx.EVT_CHAR_HOOK
を使うのが良さそう - ikap
を参考にしてほしいです。以下の本記事ではwx.EVT_KEY_DOWN
を利用しています。
本文
PhoenixのEventは、 Events and Event Handling — wxPython Phoenix 3.0.3 documentation によると2種類に大別できる。
wx.Eventから派生したクラス
とwx.CommandEventから派生したクラス
である。
違いは、親にイベントを伝播できるかどうかである。前者はこれをできず、後者は可能である。
# 前者の伝播できない例
import wx
class Panel1(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDownPanel)
def OnKeyDownPanel(self, evt):
print('I am panel1. ここは呼ばれる')
# これが無視されてしまう
evt.Skip()
class Frame1(wx.Frame):
def __init__(self, parent):
super().__init__(parent)
panel = Panel1(self)
# KeyEventはwx.Eventの派生クラスで伝播できない
self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDownFrame)
self.SetSize(240, 300)
self.Show()
def OnKeyDownFrame(self, evt):
print('I am frame1. ここは呼ばれない')
app = wx.App()
example = Frame1(None)
app.MainLoop()
は、これしか出力しない。
>>> I am panel1. ここは呼ばれる
一方で、
# 後者の例
import wx
class Button1(wx.Button):
def __init__(self, parent):
super().__init__(parent)
self.SetLabelText('伝播')
self.Bind(wx.EVT_BUTTON, self.OnPressButton)
def OnPressButton(self, evt):
print('I am Button1. 呼ばれるよ')
evt.Skip()
class ExampleCommandEvent(wx.Frame):
def __init__(self, parent):
super().__init__(parent)
self.Bind(wx.EVT_BUTTON, self.OnPress)
btn = Button1(self)
# 直観的には以下のような実装するとおもいます
# btn.Bind(wx.EVT_BUTTON, self.OnPress)
# このようにすると、self.OnPressだけ呼べる
self.Show()
def OnPress(self, evt):
print('I am ExampleCommandEvent. 伝播されたよ')
ex = wx.App()
ExampleCommandEvent(None)
ex.MainLoop()
次を出力する
>>> I am Button1. 呼ばれるよ
>>> I am ExampleCommandEvent. 伝播されたよ
まあ、後者のButtonの方はあまりしない書き方ですけども。伝播するよ、 という例を示したかっただけですので、ご容赦ください。
KeyEventがSkipできないのは個人的によろしくないので、なんとかしたい。
ありました。 wxpython - about event.Skip() - Stack Overflow
イベントをポスト出来る模様。 なので、伝播できなかったPanel1を以下のようにすれば良い
class Panel1(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDownPanel)
def OnKeyDownPanel(self, evt):
print('I am panel1. ここは呼ばれる')
# これでFrameに伝わる
wx.PostEvent(self.GetParent(), evt)
出力される:
>>> I am panel1. ここは呼ばれる
>>> I am frame1. ここは呼ばれない
要するに、CommandEventの派生クラスでない時は、wx.PostEvent(self.GetParent(), evt)すれば親に渡せる
コメント