【问题标题】:wxWidgets/wxPython: Do two identical events cause two handlings?wxWidgets/wxPython:两个相同的事件会导致两个处理吗?
【发布时间】:2010-04-04 15:03:41
【问题描述】:

当事件循环中有两个相同的事件时,wxPython 会同时处理它们,还是只为它们调用一次处理程序?

我的意思是,在我的小部件中,我想要一个像 EVT_NEED_TO_RECALCULATE_X 这样的事件。我希望在需要重新计算 x 的各种不同情况下发布此事件。但是,即使有两种不同的原因需要重新计算x,也只需重新计算一次。

我该怎么做?

编辑:

我试过这段代码:

import wx

class Frame(wx.Frame):
    def __init__(self, parent=None):
        wx.Frame.__init__(self, parent)

        self.Bind(wx.EVT_COLOURPICKER_CHANGED, self.on_event)

        self.Centre()
        self.Show(True)

        self.i = 0

        self.event_all()

    def on_event(self, event):
        print self.i
        self.i += 1

    def event_all(self):
        for j in range(1000):
            event = wx.PyEvent()
            event.SetEventType(wx.EVT_COLOURPICKER_CHANGED.evtType[0])
            wx.PostEvent(self, event)


app = wx.App()
Frame(None)
app.MainLoop()

如果事件确实组合在一起,我希望它不会一直计数到 1000。但确实如此。他们是否被分组?

【问题讨论】:

    标签: python events wxpython wxwidgets


    【解决方案1】:

    你在谈论三件事

    • 事件
    • 事件来源
    • 事件处理

    事件是单个事件(X 需要重新计算)。它有多个来源。但它只有一个处理程序。

    所以它应该可以正常工作。您将其设为单个事件,向其添加单个处理程序,但可以随时发出信号/引发事件 - 每次引发 need X recalculated 标志时,处理程序应该运行一次。


    编辑:

    这一行...

    event = wx.PyEvent()
    

    ...创建一个事件。这意味着发生了一些事情,必须做出反应。 如果你创建 1000 个事件,那么事件处理程序肯定会被调用 1000 次。

    每次事件发生时都会调用一次处理程序,也就是说,对于每个发布到事件队列的PyEvent 实例调用一次。

    如果您想对它们分组,一种方法是不创建新的PyEvent 实例(如果有一个待处理):

    class Frame(wx.Frame):
        def __init__(self, parent=None):
            wx.Frame.__init__(self, parent)
            self.Bind(wx.EVT_COLOURPICKER_CHANGED, self.on_event)
            self.Centre()
            self.Show(True)
            self.i = 0
            self.recalculating = False
            self.event_all()
    
        def on_event(self, event):
            self.recalculating = False
            print self.i
            self.i += 1
    
        def event_all(self):
            for j in range(1000):
                if not self.recalculating:
                    event = wx.PyEvent()
                    event.SetEventType(wx.EVT_COLOURPICKER_CHANGED.evtType[0])
                    wx.PostEvent(self, event)
                    self.recalculating = True
    

    【讨论】:

    • 等等,我需要实际创建这个 need X recalculated 标志还是为我创建?
    【解决方案2】:

    如果您将发布 1000 次事件,您将收到 1000 次,为什么任何事件系统会将它们分组,那将是一个错误。

    如果您不想处理所有 1000 个事件,请忽略它们,也只有您可以决定如何对它们进行分组,如果用户快速更改某些内容,您是否希望对这些更改进行分组或响应所有事件并获得更好的响应式用户界面?

    在你的情况下,你应该要么

    1. 按时间分组,例如处理相隔 N 毫秒的事件
    2. 用值分组,例如如果最后一个值与当前值相同,则什么也不做
    3. 设置一个标志是一个对象已被修改,你得到事件,你做某事并重置标志,所以下次事件检查标志是否真的发生了变化

    但底线是您必须决定如何应对事件。

    【讨论】:

      猜你喜欢
      • 2013-10-28
      • 2015-03-17
      • 1970-01-01
      • 2019-01-28
      • 1970-01-01
      • 1970-01-01
      • 2021-11-27
      • 2021-08-03
      • 1970-01-01
      相关资源
      最近更新 更多