Reputation: 330
Here is strange issue I'm facing with wxpython on Mac. Though this works completely fine with wxpython on Windows7. I'm trying to update wx.StaticText label before and after time.sleep() like this:
self.lblStatus = wx.StaticText(self, label="", pos=(180, 80))
self.lblStatus.SetLabel("Processing....")
time.sleep(10)
Above code, the label "Processing..." do not get visible until time.sleep() completes its 10 seconds. i.e. SetLabel takes effect after 10 seconds.
On windows7/wxpython works as expected but on Mac I'm facing the issue.
Upvotes: 0
Views: 585
Reputation: 33071
I have never seen time.sleep() NOT block the GUI on Windows. The sleep function blocks wx's main loop, plain and simple. As JHolta mentioned, you can put the sleep into a thread and update the GUI from there, assuming you use a threadsafe method, such as wx.CallAfter, wx.CallLater or wx.PostEvent.
But if you just want to arbitrarily reset a label every now and then, I think using a wx.Timer() is much simpler.
Upvotes: 1
Reputation: 2200
The wxPython gui is a loop, to make a part of the code sleep without causing the gui to sleep one would need to multithread.
I would write a function that calls a threaded function, now this is a dirty example but should show you what needs to be done:
import wx
from threading import Thread
import time
from wx.lib.pubsub import setuparg1
from wx.lib.pubsub import pub as Publisher
class Example(wx.Frame):
def __init__(self, *args, **kw):
super(Example, self).__init__(*args, **kw)
self.SetTitle('This is a threaded thing')
self.st1 = wx.StaticText(self, label='', pos=(30, 10))
self.SetSize((250, 180))
self.Centre()
self.Show(True)
self.Bind(wx.EVT_MOVE, self.OnMove)
# call updateUI when the thread returns something
Publisher.subscribe(self.updateUI, "update")
def OnMove(self, evt):
''' On frame movement call thread '''
x, y = evt.GetPosition()
C = SomeClass()
C.runthread(x, y)
def updateUI(self, evt):
''' Update label '''
data = evt.data
self.st1.SetLabel(data)
class SomeClass:
def runthread(self, x,y):
''' Start a new thread '''
t = Thread(target=self._runthread, args=(x,y,))
t.start()
def _runthread(self, x,y):
''' this is a threaded function '''
wx.CallAfter(Publisher.sendMessage, "update", "processing...")
time.sleep(3)
wx.CallAfter(Publisher.sendMessage, "update", "%d, %d" % (x, y))
def main():
ex = wx.App()
Example(None)
ex.MainLoop()
if __name__ == '__main__':
main()
Now the thread is initialized as soon as you try to move the "frame"/window, and will return the current placing of the window.
wx.CallAfter() is a threadsafe call to the GUI-thread, and only sends the data when the GUI-thread is ready to receive. Publisher-module simplifies the task of sending the data to our thread.
I will suggest reading this: http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/
Upvotes: 0