web-dev-qa-db-ja.com

wxPython:イベントを手動で呼び出す

自分のコードから特定のイベントを手動で呼び出すにはどうすればよいですか?

21
Ram Rachum

古いトピックですが、長い間混乱していたので、これは理解できたと思います。他の誰かがここを通り抜けて答えを探しているなら、これは役立つかもしれません。

イベントを手動で投稿するには、

self.GetEventHandler().ProcessEvent(event)

(wxWidgets docs here 、wxPython docs here

または

wx.PostEvent(self.GetEventHandler(), event)

wxWidgets docswxPython docs

ここで、eventは投稿するイベントです。たとえば、イベントを作成します。

wx.PyCommandEvent(wx.EVT_BUTTON.typeId, self.GetId())

eVT_BUTTONイベントを投稿する場合。 PyCommandEvent にすると、上向きに伝播することを意味します。他のイベントタイプはデフォルトでは伝播しません。

また、必要なデータを運ぶことができるカスタムイベントを作成することもできます。次に例を示します。

myEVT_CUSTOM = wx.NewEventType()
EVT_CUSTOM = wx.PyEventBinder(myEVT_CUSTOM, 1)

class MyEvent(wx.PyCommandEvent):
    def __init__(self, evtType, id):
        wx.PyCommandEvent.__init__(self, evtType, id)
        myVal = None

    def SetMyVal(self, val):
        self.myVal = val

    def GetMyVal(self):
        return self.myVal

(このコードはどこかのメーリングリストアーカイブで見つけたと思いますが、再び見つけることができないようです。これがあなたの例である場合は、ありがとうございます!コメントを追加してクレジットを取得してください!)

では、カスタムイベントを投稿するには:

event = MyEvent(myEVT_CUSTOM, self.GetId())
event.SetMyVal('here is some custom data')
self.GetEventHandler().ProcessEvent(event)

他のイベントと同じようにバインドできます

self.Bind(EVT_CUSTOM, self.on_event)

イベントハンドラーでカスタムデータを取得します

def on_event(self, e):
    data = e.GetMyVal()
    print 'custom data is: {0}'.format(data)

または、カスタムデータをイベントコンストラクターに含めて、ステップを保存します。

class MyEvent(wx.PyCommandEvent):
    def __init__(self, evtType, id, val = None):
        wx.PyCommandEvent.__init__(self, evtType, id)
        self.myVal = val

等.

これが誰かに役立つことを願っています。

57
David

最近のバージョンのwxPythonでそれを行う簡単で簡単な方法があります( http://wiki.wxpython.org/CustomEventClasses を参照):

   # create event class
   import wx.lib.newevent
   SomeNewEvent, EVT_SOME_NEW_EVENT = wx.lib.newevent.NewEvent()

   # post it, with arbitrary data attached
   wx.PostEvent(target, SomeNewEvent(attr1=foo, attr2=bar))

   # bind it as usual
   target.Bind(EVT_SOME_NEW_EVENT, target.handler)
5
Dan Lenski

他の回答で言及されているPostEventProcessEventのようなメソッドは、これを行うことができますが、重大な制限があることに注意してください。

  • 簡単に作成できるイベントには制限があります。たとえば、コンストラクターはキーコードを受け取らず、セッターも存在しないため、特定のキーコードを使用してwx.KeyEventを作成する方法はありません。これには回避策があるかもしれませんが(サブクラス化KeyEventなど)、基本的にフレームワークの制限をハックする必要があります。
  • クリックイベントのように、作成できるイベントの場合でも、プログラムでイベントをディスパッチすることで得られる動作は、得られる動作とは一致しません。イベントのnative処理は発生しないため、実際にユーザーとしてアクションを実行することから。たとえば、プログラムでテキストフィールドに対してクリックイベントを発生させても、テキストフィールドにフォーカスはありません。

ほとんどの場合、PostEventまたはProcessEventを使用しないことをお勧めします。イベント処理関数を実行するだけの場合は、手動でイベントを作成しても意味がありません。代わりに、関数を明示的に呼び出すだけです。自動化されたUIテストを作成しようとしているためにそれらが必要な場合は、上記の制限のために、満足のいくものが得られない可能性があります。代わりに、 wx.UIActionSimulator を使用して、OS /デスクトップマネージャーのレベルでクリックとキー押下を実際にシミュレートするものを作成することをお勧めします。それは一種の粗雑であり、システムのマウスとキーボードを制御するため、通常、開発マシンで実行するテストスイートには不適切なテストになります...しかし、少なくともそれは動作します、これはPostEventでイベントをディスパッチするために言うことができる以上のものです。

3
Mark Amery

イベントディスパッチをしたいということですか?

:: wxPostEvent void wxPostEvent(wxEvtHandler * dest、wxEvent&event)

GUIアプリケーションでは、この関数はwxEvtHandler :: AddPendingEventを使用して指定されたdestオブジェクトにイベントを送信します。それ以外の場合は、wxEvtHandler :: ProcessEventを使用してイベントをすぐにディスパッチします。詳細(および警告)については、それぞれのドキュメントを参照してください。

ファイルを含める

<wx/app.h>

wxPython APIドキュメント

0
Bjorn Tipling

イベントが何に関連付けられているかによると思いますが、リストでアイテムを選択したときにデータを表示するLabelFrameでも同じことを行う必要がありました。これは私がそれをすることができた方法です:

'This is the line that binds my function "get_selected_location()"
to the action of selecting an item in my List box.'

self.list1_scoring.bind('<<ListboxSelect>>', self.get_selected_location)

したがって、「list1_scoring」ボックスのアイテムをクリックすると、get_selected_location()が実行され、選択されたアイテムに関する詳細が別のLabelFrameに表示されます。更新プロセスが完了した後、このイベントを呼び出して表示ウィンドウを更新する必要がありました。そのため、更新を実行する関数の最後にこの行を追加しました。

self.get_selected_location('<<ListboxSelect>>')

これにより、リストをもう一度クリックしたかのように、get_selected_location()が再度実行されます。

0
NL23codes