【问题标题】:wxPython: Calling an event manuallywxPython:手动调用事件
【发布时间】:2010-10-19 08:48:11
【问题描述】:

如何从我自己的代码中手动调用特定事件?

【问题讨论】:

    标签: python user-interface events wxpython


    【解决方案1】:

    老话题,但我想我在困惑了很长时间后已经弄清楚了,所以如果其他人来这里寻找答案,这可能会有所帮助。

    要手动发布事件,您可以使用

    self.GetEventHandler().ProcessEvent(event)
    

    (wxWidgets 文档here,wxPython 文档here

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

    (wxWidgets docs, wxPython 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
    

    等等

    希望这对某人有所帮助。

    【讨论】:

      【解决方案2】:

      我想你想要wx.PostEvent

      还有一些关于从其他线程为long running tasks on the wxPython wiki 发布事件的信息。

      【讨论】:

        【解决方案3】:

        使用最新版本的 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)
        

        【讨论】:

          【解决方案4】:

          虽然其他答案中提到的 PostEventProcessEvent 等方法可以做到这一点,但请注意它们有很大的局限性:

          • 您可以轻松创建的事件受到限制。例如,没有办法使用特定的键码创建wx.KeyEvent,因为构造函数不采用键码并且没有设置器。也许有一些解决方法(比如子类化KeyEvent),但你基本上不得不绕过框架的限制。
          • 即使对于您可以创建的事件(例如单击事件),您通过以编程方式调度事件获得的行为也不会与您作为用户实际执行该操作获得的行为相匹配, 因为事件的 native 处理不会触发。例如,以编程方式在文本字段上触发点击事件不会使文本字段获得焦点。

          我建议不要在大多数情况下使用PostEventProcessEvent。如果你只是为了让你的事件处理函数运行,那么手动创建事件是没有意义的;相反,只需显式调用该函数。如果你想要它们是因为你正在尝试编写一个自动化的 UI 测试,那么由于上面列出的限制,你最终可能不会得到满足你的东西;相反,我建议使用wx.UIActionSimulator 在操作系统/桌面管理器级别编写实际模拟点击和按键的内容。这有点恶心,并且会控制您系统的鼠标和键盘,这通常会使此类测试不适合您在开发机器上运行的测试套件......但至少它工作,这是使用PostEvent 调度事件的意义不止于此。

          【讨论】:

            【解决方案5】:

            我想这取决于您的事件与什么相关联,但是当您在列表中选择一个项目时,我需要对显示数据的 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(),就好像我刚刚再次单击了我的列表一样。

            【讨论】:

              【解决方案6】:

              你的意思是你想要一个事件调度?

              ::wxPostEvent 无效 wxPostEvent(wxEvtHandler *dest, wxEvent&事件)

              在 GUI 应用程序中,此函数 将事件发布到指定的目的地 对象使用 wxEvtHandler::AddPendingEvent。 否则,它会分派事件 立即使用 wxEvtHandler::ProcessEvent。见 有关详细信息的相应文档 (和注意事项)。

              包含文件

              &lt;wx/app.h&gt;

              wxPython API docs

              【讨论】:

              • 我不会 C,这很混乱。你能给我我应该运行的 Python 行吗?
              • 我认为是一样的。 wx.core.PostEvent?检查:google.com/…
              • 我在 wx 主命名空间和 Event 的命名空间中都没有看到它。
              • wx.PostEvent 是函数,它的工作方式相同。 wx.PostEvent(窗口,事件)
              • 谁能解释什么是“typeID”以及它与“EVT_BUTTON”有何关系?
              猜你喜欢
              • 2017-01-07
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-01-19
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多