wxPython 忽略或删除事件
我的程序有几个按钮,当点击这些按钮时,会调用一些需要花费一点时间才能完成的函数。现在遇到的问题是,有时候一个按钮会“激活”两次,导致这个函数不明原因地被执行了第二次。而且,由于这些函数运行时间较长,用户在第一个函数还在运行的时候,可能会多次点击同一个按钮,或者点击其他按钮,这样的话,其他按钮的函数会在第一个函数完成后立刻执行。
我想要做的是能够丢弃任何待处理的事件,这样这些按钮就不会重复激活,也能防止用户不小心排队执行一堆这些函数。我想我也可以在一个按钮被点击后立刻禁用所有按钮,但相比于直接清空事件队列,这种方法看起来就不太优雅。
我到处查找,似乎有一些可以实现我想要功能的函数,但我就是不知道怎么调用它。当然,也有可能我用的wxPython版本里没有这个函数,不太确定这是否可能。
谢谢
3 个回答
0
你可能应该这样做(记住,这只是一个非常简单的例子)
import wx ,time
import threading
def the_actual_long_task(whatever=None):
for i in range(15):
time.sleep(1)
print "TASK RUNNING!"
return whatever
my_lock = threading.Lock()
def long_task(callback,some_other_arg=None):
my_lock.acquire() #this will block until the lock is released by another thread
my_return_value = the_actual_long_task(some_other_arg)
wx.CallAfter(callback,my_return_value)
my_lock.release() #allow another thread to acquire the lock
def OnTaskDone(result):
print "Task Done!",result
my_button.Enable(True)
my_button.SetLabel("Run Task")
def OnButton(event):
t = threading.Thread(target=long_task,args=(OnTaskDone,))
t.start()
my_button.Enable(False)
my_button.SetLabel("Test In Progress...")
a = wx.App(redirect = False)
f = wx.Frame(None,-1,"Example")
my_button = wx.Button(f,-1,"Run Task",size=(200,-1))
my_button.Bind(wx.EVT_BUTTON,OnButton)
f.Show()
a.MainLoop()
使用线程来运行任务可以让你的界面不被阻塞
禁用按钮会让它在任务完成之前无法再次点击
0
正如其他人已经提到的,简单的解决办法就是在长时间运行的任务完成之前,先把按钮禁用掉。这样就不会再接受其他的按钮点击了。另一方面,你也可以在事件处理函数里调用按钮的 Unbind() 方法,把事件处理器从按钮上移除。
类似这样的代码应该可以工作:
def myEventHandler(self, event):
self.ButtonOne.Unbind(wx.EVT_BUTTON, self.myEventHandler)
另外,你可以参考以下链接:
1
当你按下一个按钮时,你可以试着把想要停止事件的窗口的 SetEvtHandlerEnabled 方法设置为 false,这样就可以停止事件的处理。等事情完成后,再把它设置回 true。