I am having trouble with setting the focus of a button AFTER a modal dialog is destroyed.
Is there a call I can make to destroy the modal dialog or to stop it from being modal and then destroy it?
When the wx.PostEvent triggers an event it forces a Destroy on a modal dialog however as I understand it, it doesn't get destroyed immediately which means that the buttons are still disabled when I do a SetFocus().
import wx
import wx.lib.newevent
from threading import Thread
import time
processFinishes, EVT_PROCESS_FINISHES = wx.lib.newevent.NewEvent()
class Dummy(Thread):
def __init__(self, arg):
super(Dummy, self).__init__()
self.arg = arg
def run(self):
time.sleep(15)
print "Posting"
wx.PostEvent(self.arg , processFinishes(result=(None)))
class MyRegion(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent)
self.button = wx.Button(self, label="Click me!")
self.mybutton2 = wx.Button(self, label="I should have focus!!!")
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.button, 0, wx.ALL)
sizer.Add(self.mybutton2, 0, wx.ALL)
self.SetSizerAndFit(sizer)
self.Bind(wx.EVT_BUTTON, self.OnButton)
self.Bind(EVT_PROCESS_FINISHES, self.OnFinish)
self.progress = None
self.t = Dummy(self)
def OnButton(self, event):
self.progress = wx.ProgressDialog("Processing",
"Please wait while the processing finishes.")
self.progress.Pulse()
self.progress.ShowModal()
self.t.start()
def OnFinish(self, _event):
print "destroyed"
self.progress.Destroy()
print "now setting foucs"
self.mybutton2.SetFocus()
if __name__ == "__main__":
app = wx.App()
frame = MyRegion(None)
frame.Show()
app.MainLoop()
EDIT:
When attempting to stop the progress dialog from being modal, the following code gives me errors indicating that the ProgressDialog is not modal whereas it clearly is:
.....
def OnButton(self, event):
# wx.ProgressDialog can also be created with
# style=wx.wx.PD_APP_MODAL which cannot be made non-modal later on
# i.e. EndModal() does not work
self.progress = wx.ProgressDialog("Processing",
"Please wait while the processing finishes.")
self.progress.Pulse()
self.progress.ShowModal()
self.t.start()
def OnFinish(self, _event):
print "destroyed"
# By changing this line
# wx complains indicating that the progress dialog
# is not modal whereas a ShowModal was used
self.progress.EndModal(0) # -> produces a "wx._core.PyAssertionError: C++ assertion "IsModal()" failed at ..\..\src\msw\dialog.cpp(221) in wxDialog::EndModal(): EndModal() called for non modal dialog"
print "now setting foucs"
self.mybutton2.SetFocus()
The modal dialog reenables everything by the time ShowModal()
returns, so just call OnFinish()
directly from OnButton()
.
However notice that wxProgressDialog
is not a modal dialog at all (it would be pretty useless if it were as you wouldn't be able to call Update()
on it!), so in its case you should just destroy it when you are done with it (or use wxPD_AUTO_HIDE
style to tell it to go away on its own when maximal progress value is reached).