1

で最近勉強中なのですが、第3章、特にのダイヤの説明でwxPython行き詰まっwxPython in ActionてしまいましたFigure 3.3Skip()

ではStep 3 Locating the binder object、本は次のように書いています。

オブジェクト自体のバインダーが見つからない場合、処理はクラス階層を上って、オブジェクトのスーパークラスで定義されたバインダーを見つけます。次のステップ。

しかし、次のステップで、次のようにStep 4 Determining whether to continue processing書いています。

イベント ハンドラーは、wx.Event メソッド Skip() を呼び出して、さらに処理を要求します。Skip() メソッドが呼び出されると、処理が続行され、( 2 ) スーパークラスで定義されたハンドラーが検出され、ステップで実行されます。Skip() メソッドは、ハンドラーの任意の時点で呼び出すことができます。Skip() メソッドは、wxPython がハンドラー メソッドの完了後にチェックするイベント インスタンスにフラグを設定します。リスト 3.3 では、OnButtonClick() は Skip() を呼び出さないため、その場合、イベント プロセスはハンドラ メソッドの最後で完了します。他の 2 つのイベント ハンドラーは Skip() (4) を呼び出すため、システムは一致するイベント バインディングを検索し続けます(5) 最終的に、マウス オーバー イベントなどのネイティブ ウィジェットのマウス エンター イベントおよびマウス リーブ イベントのデフォルト機能を呼び出します。

私の質問は、文章でマークした数字に関連しています。

(1)私の理解と他のいくつかのグーグル資料では、伝播はクラス階層ではなくコンテナ階層で何かが起こることです、これは正しいですか?

(2) マジ?ハンドラは実行されますか? インスタンスとイベントの組み合わせに一致するものではありませんか?

(3)ここのスーパークラスは正しいですか? 親ウィンドウであってはいけませんか?

(4) この行は質問 2 と矛盾していると思いますが、インスタンスとイベントの組み合わせに一致するハンドラーだけが実行されているのではないでしょか?

(5) とはdefault functionality?そしてそれはどのように呼び出されますか?

興味のある方は、listing-3.3.py をご覧ください:

import wx


class MouseEventFrame(wx.Frame):

    def __init__(self, parent, id):
        wx.Frame.__init__(self, parent, id, 'Mouse Events',
                          size=(300, 200))
        self.panel = wx.Panel(self)
        self.button = wx.Button(self.panel,
                                label='Not Over', pos=(100, 15))
        self.Bind(wx.EVT_BUTTON, self.OnButtonClick, self.button)
        self.button.Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow)
        self.button.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow)

    def OnButtonClick(self, event):
        self.panel.SetBackgroundColour('Green')
        self.panel.Refresh()

    def OnEnterWindow(self, event):
        self.button.SetLabel('Over Me!')
        event.Skip()

    def OnLeaveWindow(self, event):
        self.button.SetLabel('Not Over')
        event.Skip()


if __name__ == '__main__':
    app = wx.App()
    frame = MouseEventFrame(parent=None, id=-1)
    frame.Show()
    app.MainLoop()
4

1 に答える 1

6

オブジェクトに関連付けられたイベントが生成されると、ハンドラー ルックアップの順序は次のようになります。

  1. wxApp::FilterEvent()
  2. オブジェクト自体にプッシュされたイベント ハンドラー。これが wxPython で公開されているかどうかさえわかりません。いずれにせよ、これはもう使用しないでください。
  3. 最も派生したクラスに登録されたハンドラーから始まり、基本クラスで定義されたハンドラーに続く、オブジェクト自体。
  4. イベントが「伝播可能」である場合 (デフォルトではそうですwxCommandEventが、たとえば、そうではありませんwxMouseEvent)、オブジェクトがウィンドウの場合、オブジェクトのすべての親ウィンドウが再帰的に。
  5. wxTheApp自体。
  6. 最後に、基礎となるツールキット レベルのイベントのデフォルト ハンドラーが使用されます。どちらかといえば、正確なイベントの種類とプラットフォームに依存しますが、一部のイベントでは、それを呼び出せるようにすることが非常に重要です。特に、フォーカス イベントでは、デフォルトのネイティブ コントロール ハンドラーがそれらを更新するためにそれらを取得できるようにする必要があります。集中状態。

さて、どうSkip()ですか?通常、検索中に見つかった最初のハンドラが使用され、イベント処理はそこで停止します。ただしevent.Skip()、実行中にハンドラーが呼び出された場合、このイベント ハンドラーはスキップされ、検索が続行されます。つまり、理解しておくべき重要なことはSkip()、イベント オブジェクトで呼び出されたとしても、イベントをスキップしないということです。代わりに、それを呼び出すイベント ハンドラーをスキップします。

ハンドラーを呼び出すことが重要な理由が理解できたと思いevent.Skip()ます。wxFocusEvent

于 2013-11-11T12:25:01.043 に答える