I've made a runnable example that demonstrates the buggy behavior: http://pastebin.com/8KpzD4pw
This issue is EXTREMELY aggravating. I have a wx.ProgressDialog
up while I'm saving a file, and upon IOError
, I want to close the progress dialog and display an error message. Unfortunately, this seems to be impossible. The progress dialog blatantly refuses to close before the message box closes:
As you can see, the message box appears below the progress dialog, so the user has to manually switch focus to the message box to see it's contents. When the message box is closed, the progress dialog disappears as well. Here is the code for the save function:
def save(self, path=None):
# Show a loading dialog while the document is staving.
progress = shared.show_loading(self, 'Saving document')
try:
raise IOError('Error message')
if not path:
self.document.save()
else:
self.document.save_to_file(path)
except IOError as e:
progress.done()
message = 'Failed to save file:\n\n{}'.format(e.message)
wx.MessageBox(message, 'Error', wx.OK | wx.ICON_ERROR)
progress.done()
The show_loading
and progress.done
functions are just shortcuts for using the wx.ProgressDialog
(source).
I have also tried using wx.CallAfter
to open the message box, to no avail:
# ...
except IOError as e:
message = 'Failed to save file:\n\n{}'.format(e.message)
def show_error():
wx.MessageBox(message, 'Error', wx.OK | wx.ICON_ERROR)
progress.done()
wx.CallAfter(show_error)
# ...
I have also tried to sleep for 100ms between closing the progress dialog and opening the message box using wx.MicroSleep
without success.
I have also tried calling wx.Yield()
and wx.WakeUpIdle()
right after destroying the progress dialog, neither having any effect.
I had a similar case, which I finally resolved by calling:
dlg.Update( dlg.GetRange( ) )
It seems that, at least when you put the progress dialog into "pulse" mode, it won't immediately respond to Destroy calls. No amount of sleeping or yielding before or after destroying it would convince my progress dialog to stop displaying. However, by instead simply updating the value to the max, it seems to automatically destroy (or at least hide) itself immediately.