This is probably the right track. I've appended a small working example
that does what I think you want.
DemoFrame is just a frame with a button you can click to start the
calculation. DemoDialog does the interesting stuff. It starts a thread
to run the calculation, then calls ShowModal() on itself. Because it
has no buttons, the user can't dismiss it. The calculation, in its own
thread, does its stuff then calls EndModal(0) on the wx.Dialog. Because
it's not in the GUI thread, it has to use wx.CallAfter to call
GUI-related functions safely.
Hope this makes sense.
Simon.
···
On Tue, Jul 04, 2006 at 10:06:34AM +0200, Thomas wrote:
Hello!
During some calculations I want to show a window with a message what I'm
actually doing. This window must be modal to prevent other actions on
the GUI and so there should be no chance to kill this window by the
user. Killing should only be done by the software, when the calculations
are finished.
I played with modal dialogs, but as the name says, the ShowModal()
method just returns after a user action, which I don't want.
--------------------------------------------
import threading,time,wx
BUTTONID=101
class DemoFrame(wx.Frame):
def __init__(self):
# Set up a frame with a single button labelled "Click me"
wx.Frame.__init__(self,None,-1,"Demo")
self.ctrl=wx.Button(self,BUTTONID,"Click me")
self.Bind(wx.EVT_BUTTON,self.onClick,self.ctrl)
self.Show()
def onClick(self,event):
# When the button is clicked, call the constructor of DemoDialog
print "Received click"
DemoDialog(self)
print "Finished"
class DemoDialog(wx.Dialog):
def __init__(self,parent):
# Draw a label saying what we're doing
N=5
wx.Dialog.__init__(self,parent,-1,"Wait for it....")
self.label=wx.StaticText(self,-1,"Thinking for "+str(N)+"s")
# Start up a thread to do the calculations (self.run(N))
t=threading.Thread(target=self.run,args=(N,))
t.setDaemon(True)
t.start()
# Show the dialog, blocking user actions except for this dialog,
# which has no buttons
self.ShowModal()
def run(self,n):
# Re-write the label, counting down to 0. Note the use of
# wx.CallAfter
# to make any calls to the GUI because we're in a non-GUI
# thread.
# Replace this bit with your calculations.
t=time.time()
currentT=n
while time.time()<t+n:
if int(time.time()-t)!=n-currentT:
currentT-=1
wx.CallAfter(self.label.SetLabel, \
"Thinking for "+str(currentT)+"s")
# Pop down the window. Keep this bit!
wx.CallAfter(self.EndModal,0)
class DemoApp(wx.App):
def OnInit(self):
DemoFrame()
return True
app=DemoApp()
app.MainLoop()