Reputation: 489
Disabled button still catch clicks during the long task. During the long tasks the button is grayed out but if you click it during the long task, click event fires after the long task has finished. e.g.
def onClick(self, evt):
self.btn.Disable()
for i in range (1000):
print i
self.btn.Enable()
Button disables itself before executing the long for loop, but if we click the button during for loop, it starts the for loop again, because it calls the onClick function again, after the for loop finishes.
Any idea how to disable the click event as well ?
Upvotes: 1
Views: 332
Reputation: 22443
In fact it's easier than my first answer suggested. There is no reason to UnBind
, simply using Yield
before re-enabling the button will suffice:
import wx
import time
class ButtonFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None,-1,"Disable Button Events")
panel = wx.Panel(self, -1)
self.btn = wx.Button(panel, -1, "Click Me", pos=(10,10), size=(80,30))
self.btn.Bind(wx.EVT_BUTTON, self.onClick)
self.Show()
def onClick(self, event):
self.btn.Disable()
for i in range (10):
time.sleep(1)
print("Long task running",i)
wx.GetApp().Yield() # Yielding allows button events to be used up
self.btn.Enable()
print("Accepting clicks again")
if __name__ == "__main__":
app = wx.App()
ButtonFrame()
app.MainLoop()
Upvotes: 0
Reputation: 22443
Although I have my doubts as to whether you should be coding your long running event this way, you can achieve what you want by using Unbind
on the button click, perform the long running task, using Yield
to use up any subsequent button clicks and then at the end of the task Bind
to the button again.
i.e.
import wx
import time
class ButtonFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None)
self.btn = wx.Button(self, -1, "Click Me")
self.btn.Bind(wx.EVT_BUTTON, self.onClick)
self.Centre()
self.Show()
def onClick(self, event):
self.btn.Unbind(wx.EVT_BUTTON)
for i in range (10):
time.sleep(1)
print( i )
wx.GetApp().Yield() # Yielding allows button events to be used up
self.btn.Bind(wx.EVT_BUTTON, self.onClick)
print ("Accepting clicks again")
if __name__ == "__main__":
app = wx.App()
ButtonFrame()
app.MainLoop()
Upvotes: 1
Reputation: 115
To be honest I didn't really get what you are asking.
Your code works as follows:
If you would like to disable the button, you should do it outside of the onclick event. For example:
self.btn.Disable() # This will grey out the button, you can't click it, so the following onClick function wouldn't be triggered
def onClick(self, evt):
# do something
If you would like to use the button to trigger a task execution, and disable the button that triggers the task when the task is in the middle of execution, the best way is to use multi-thread. You can take a look at the following two links for more information:
http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/ https://wiki.wxpython.org/LongRunningTasks
Upvotes: 0