5

私は wxPython の比較的経験豊富なユーザーですが、wxPython が複数のイベント ハンドラーを同じイベントにバインドする方法に常に問題を抱えていました (私が一般的であることはわかっています。以下の例がより具体的であることを願っています)。これは、wxPython コミュニティで通常言及されている「イベントの伝播」に関する質問ではありません。

サンプル コードは次のとおりです (正しくない場合: フォーラムのコード ブロック システムを理解するのに苦労しました)。

import wx

class MainFrame(wx.Frame):
    def __init__(self, parent, ID, title):
       wx.Frame.__init__(self, parent, ID, title,
                      wx.DefaultPosition, wx.Size(200, 100))

       Panel = wx.Panel(self, -1)
       TopSizer = wx.BoxSizer(wx.VERTICAL)
       Panel.SetSizer(TopSizer)

       Text = wx.TextCtrl(Panel, -1, "Type text here")
       TopSizer.Add(Text, 1, wx.EXPAND)

       Text.Bind(wx.EVT_KEY_DOWN,self.OnKeyText)
       Text.Bind(wx.EVT_KEY_DOWN, self.OnKeyText2)


    def OnKeyText(self, event):
        print "OnKeyText"
        event.Skip()

    def OnKeyText2(self, event):
        print "OnKeyText2"
        event.Skip()

class MyApp(wx.App):
    def OnInit(self):
        Frame = MainFrame(None, -1, "Event Order Demo")
        Frame.Show(True)
        self.SetTopWindow(Frame)
        return True

if __name__ == '__main__':
    App = MyApp(0)
    App.MainLoop()

関数 "OnKeyText2" が最初に実行されるので、このコントロールの "イベント スタック" (wxPython のこの部分に "イベント スタック" ではなく適切な用語はありますか?) の動作は次のようになります。同じ伝播レベルの同じイベントは、スタックの一番上 (最初に実行) に移動し、一番下 (2 番目に実行) には移動しません。

私はこれを理解していますが、基本クラスの関数がいくつかのイベントをバインドするクラスのサブクラスがあり、サブクラスが追加のイベントを後からバインドするため、私のアプリケーションでは本当に面倒です。

イベントが「イベントスタック」に逆向きに入れられるような気がします(最後に発生させたいイベントを最初にバインドします)。イベントを「イベントスタック」に追加し、最初に挿入しないようにする方法はありますか?

event.Skip() コマンドを誤解している、または何か不足している場合は、お知らせください。:)私がやろうとしていることを行うためのより良い方法はありますか? イベントをつなぎ合わせたくありません (たとえば、OnKeyText() を実行したら、OnKeyText2() を呼び出します)。私のアプリでは、イベント ハンドラーの 1 つがすべてのサブクラスで共有され、もう 1 つが共有されていないためです。

答えが「逆の順序で実行する必要がある」という場合は、それを受け入れてアプリに変更を加える必要があります。

答えが、コントロールとパネル間のイベント伝達を使用してイベント ハンドラーの順序を制御する必要がある場合、イベント ハンドラーの数を伝達レベルごとに 1 つに維持しないと、同じ問題に遭遇するように感じます。

前もって感謝します!ベンジャミン

4

1 に答える 1

0

あなたの場合、なぜ順序が重要なのか理解できませんが、同様の問題がありました.

私はもともと複数の に対して 1 つのイベント ハンドラーを持っていましたTextCtrlが、実際にはEVT_TEXT_ENTER. 次に、テキスト フィールドに正の整数を期待していたので、入力された文字列を検証したいと思いました。TextCtrlその目的のためにサブクラス化し、文字列検証のためにサブクラスにイベント ハンドラーをフックしました。

もちろん、問題がありましTextCtrlた。サブクラスのイベント ハンドラによる検証がスーパークラスのイベント ハンドラによる作業の前に行われた場合、s の半分だけで問題なく動作しました。

ハンドラーが内部でどのように管理/処理されているかは調査しませんでしたが、代わりに設計を修正しました。サブクラスのイベント ハンドラーはEVT_TEXT_ENTER、文字列が検証された後、私が導入したカスタム イベントにバインドされます。スーパークラス イベント ハンドラーは、 ではなく、このカスタム イベントにフックされるようになりましたEVT_TEXT_ENTER

このようにして、私は常に処理順序を確信しており、バインド解除/再バインドの影響を受けません。文字列の検証が前提条件である場合は、カスタム イベントにさらに多くのハンドラーをフックできます。

于 2012-11-15T10:37:47.203 に答える