[wxPython-users] Re: wxProgressDialog problems
Robin Dunn
robin at alldunn.com
Tue Feb 26 13:13:40 PST 2008
Larry Bates wrote:
> =
> I appreciate your attempts to help me but I'm still dead-in-the-water. =
> For some reason the MailLoop does NOT exit immediately (even without =
> app.SetExitOnFrameDelete(False)). The messages that I post via =
> wx.PostEvent in my (non-GUI) loop DO get processed properly and the GUI =
> dialog including the title, message1 and gauge are all updated as =
> expected, but I can't click on the Cancel button (hourglass cursor =
> whenever I hover over the dialog and clicks do nothing). This is =
> soooo... close, that its frustrating.
I've made a somewhat simpler example that illustrates what I've been =
trying to say. It creates a new thread for initializing and running wx, =
so this will be the gui thread and you can continue to do your other =
stuff in the main thread. I then created a simple proxy of =
wx.ProgressDialog that uses wx.CallAfter to cause the real UI methods to =
be called in the context of the gui thread, and it also uses a =
threading.Event to cause one of the proxy methods to wait until the real =
method has completed in the gui thread so the result can be returned to =
the non-gui thread. (If you don't want to wait then there are other =
ways do handle it, such as using a callback, etc.)
I created a hidden frame because I was having troubles getting =
SetExitOnFrameDelete to work as I was expecting. I think there is a bug =
there that I'll track down, but in the meantime the hidden frame works =
just as well to keep the wx MainLoop alive.
-- =
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!
-------------- next part --------------
import threading
import time
import wx
print wx.version()
class WxThread(threading.Thread):
def run(self):
self.app =3D wx.App(redirect=3DFalse)
#app.SetExitOnFrameDelete(False)
hiddenFrame =3D wx.Frame(None)
self.app.MainLoop()
def ExitMainLoop(self):
wx.CallAfter(self.app.ExitMainLoop)
=
def start(self):
threading.Thread.start(self)
time.sleep(0.1) # give wx a chance to get started before returning
=
class ThreadSafeProgressDialog(object):
def __init__(self):
self.dlg =3D None
self.keepGoing =3D True
self.updateEvt =3D threading.Event()
=
def Create(self, title, message, maximum=3D100, parent=3DNone, style=3D=
wx.PD_AUTO_HIDE|wx.PD_APP_MODAL):
wx.CallAfter(self._Create, title, message, maximum, parent, style)
def _Create(self, *args, **kw):
self.dlg =3D wx.ProgressDialog(*args, **kw)
=
def Show(self):
wx.CallAfter(self._Show)
def _Show(self):
self.dlg.Show()
def Update(self, value, newmsg=3D""):
self.updateEvt.clear()
wx.CallAfter(self._Update, value, newmsg)
self.updateEvt.wait()
return self.keepGoing
def _Update(self, value, newmsg):
self.keepGoing, skip =3D self.dlg.Update(value, newmsg)
self.updateEvt.set()
=
def Destroy(self):
wx.CallAfter(self.dlg.Destroy)
=
# start wx in a thread
wxt =3D WxThread()
wxt.start()
# do some stuff in the main thread that needs progress dialogs
for f in ['one', 'two', 'three']:
tspd =3D ThreadSafeProgressDialog()
tspd.Create('File upload', 'file: %s' % f,
style=3Dwx.PD_APP_MODAL |
wx.PD_AUTO_HIDE | =
wx.PD_CAN_ABORT | =
wx.PD_REMAINING_TIME)
tspd.Show()
for pct in range(100):
time.sleep(0.1)
if not tspd.Update(pct):
break
tspd.Destroy()
# tell wx to exit the main loop, which will then exit the gui thread
wxt.ExitMainLoop()
More information about the wxpython-users
mailing list