I found wx.CallAfter and wx.CallLater in the documentation but neither solves my problem.
What I’m trying to do is update a status bar while doing a task, but both wx.CallAfter and wx.CallLater only updates after task.
Example:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# generated by wxGlade 0.6.3 on Fri Sep 30 20:55:34 2011
import wx
import time
# begin wxGlade: extracode
# end wxGlade
class MyFrame1(wx.Frame):
def __init__(self, *args, **kwds):
# begin wxGlade: MyFrame1.__init__
kwds["style"] = wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.frame_2_statusbar = self.CreateStatusBar(1, 0)
self.__set_properties()
self.__do_layout()
# end wxGlade
def __set_properties(self):
# begin wxGlade: MyFrame1.__set_properties
self.SetTitle("frame_2")
self.frame_2_statusbar.SetStatusWidths([-1])
# statusbar fields
frame_2_statusbar_fields = ["foo"]
for i in range(len(frame_2_statusbar_fields)):
self.frame_2_statusbar.SetStatusText(frame_2_statusbar_fields[i], i)
# end wxGlade
def __do_layout(self):
# begin wxGlade: MyFrame1.__do_layout
self.Layout()
# end wxGlade
def Test(self):
time.sleep(10)
for i in range(0,100):
time.sleep(0.1)
txt="I <3 Stack Exchange x " +str( i)
wx.CallAfter(self.frame_2_statusbar.SetStatusText,txt, 0)
wx.CallAfter(self.Update)
print txt
# end of class MyFrame1
if __name__ == "__main__":
app = wx.PySimpleApp(0)
wx.InitAllImageHandlers()
frame_1 = MyFrame1(None, -1, "")
app.SetTopWindow(frame_1)
frame_1.Show()
wx.CallAfter(frame_1.Test)
app.MainLoop()
From the sound of it, “CallDuring” is nothing more than simply calling whatever function you want. It will get called exactly when you call it. Is there a reason why calling it directly doesn’t solve your problem?
However, you’re telling your program to sleep. No amount of “call during” will help you since you’re putting the whole app to sleep. Maybe you think that
sleepis a good simulation of “real” code, but it’s not. You’re actually telling your program “stop all processing”, which includes screen updates.The crux of your problem is that you’re not allowing the event loop to process redraw events. You might try calling wx.Yield() in your loop, but having a large, long-running loop in the main thread of a GUI program is a code smell. There’s almost certainly a better way to approach your problem.
The best advice I can give is to search on “wxpython long running task”. Most likely the first hit will be a wxpywiki page titled “Long Running Tasks” that you might find helpful.