1

We are working on bringing our application up to date with wxPython 3.0.2, however this is one of two major bug that is still around.

Background: on program start, we spawn a custom dialog telling the user that some things are loading. This dialog has an animation, so it's important to keep the main thread with the GUI clear while we load data in the background thread. When that is done, we sent a command to a callback that Destroy()s the dialog, and the program is able to function as normal.

This works well in 2.8, but it seems to hang our app in 3.0. The dialog message disappears, but we cannot close the program or interact with the GUI, almost as if the GUI was still locked under Modal.

Here's a test script that demonstrates, being as close to the original program as possible in the logic path it takes:

import wxversion
wxversion.select('3.0')
import wx
import time
import threading


class OpenThread(threading.Thread):
    def __init__(self, callback):
        threading.Thread.__init__(self)
        self.callback = callback
        self.start()

    def run(self):
        time.sleep(0.5)  # Give GUI some time to finish drawing

        for i in xrange(5):
            print i
            time.sleep(.3)
        print "ALL DONE"
        wx.CallAfter(self.callback)


class WaitDialog(wx.Dialog):
    def __init__(self, parent, title = "Processing"):
        wx.Dialog.__init__ (self, parent, id=wx.ID_ANY, title = title, size=(300,30),
                           style=wx.NO_BORDER)
        mainSizer = wx.BoxSizer( wx.HORIZONTAL )
        self.SetBackgroundColour(wx.WHITE)
        txt = wx.StaticText(self, wx.ID_ANY, u"Waiting...", wx.DefaultPosition, wx.DefaultSize, 0)
        mainSizer.Add( txt, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 0 )
        self.SetSizer( mainSizer )
        self.Layout()
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        self.CenterOnParent()

    def OnClose(self, event):
        pass

class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Test")
        self.waitDialog = None

        mainSizer = wx.BoxSizer( wx.HORIZONTAL )
        choice = wx.Choice(self, wx.ID_ANY, style=0)
        choice.Append("No Selection", 0)
        choice.Append("Selection 1", 1)
        choice.Append("Selection 2", 2)

        mainSizer.Add( choice , 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 0 )
        self.SetSizer( mainSizer )


        self.Show()
        self.doThing()

    def doThing(self):
        self.waitDialog = WaitDialog(self, title="Opening previous fits")
        OpenThread(self.closeWaitDialog)
        self.waitDialog.ShowModal()

    def closeWaitDialog(self):
        self.waitDialog.Destroy()

test = wx.App(False)
MainFrame()
test.MainLoop()

You can comment out the self.waitDialog bits and see that it is the dialogs giving trouble. There are other places in the program that this happens in, always after we close out of a Dialog. Is there something I'm missing? Is there a workaround? We also have a few more dialogs that we utilize, so a workaround would ideally be a small fix rather than a huge refactoring

blitzmann
  • 7,319
  • 5
  • 23
  • 29

1 Answers1

0

wx.CallAfter basically just puts the event into a queue, so I wonder if the event queue is getting blocked somehow such that it isn't processing the event that would call your event handler to destroy the dialog.

I found the following that might help:

Basically you could use wx.WakeUpIdle() or wx.GetApp().ProcessIdle() or maybe even ProcessPendingEvents.

This might also be helpful:

I also found this useful StackOverflow answer to a similar problem in that you may just need to call the dialog's EndModal method before Destroying it.

Community
  • 1
  • 1
Mike Driscoll
  • 32,629
  • 8
  • 45
  • 88
  • That doesn't really address the problem though, and also doesn't help with the other dialogs that we have throughout the program that are also affected. As for the wait dialog - the example simply shows what is happening. We have reasons for the way it's implemented. I will look into joining threads as that's something new to me, but again, doesn't really address the issue. – blitzmann Aug 05 '15 at 18:34