user2778477
user2778477

Reputation:

wxPython: program quits but window remaines not responding after calling sys.exit

I'm writing a program that displays a specific picture in the current directory. Before creating a wx.Image object, it checks whether the picture exists. If the picture doesn't exist, it'll pop up a message dialog that says "Can not open the picture 'Tsukuyo.jpg'." Then the program will exit automatically.

However, when I ran it, it did quit (according to the interactive shell) but remained the window not responding. Why was that? Here is the code.

class MyFrame(wx.Frame):
"""Frame class."""

    def  __init__(self, parent=None, id=-1,
                  pos=wx.DefaultPosition,
                  title='Hello, Tsukuyo!', size=(200,100)):
        """Create a Frame instanc."""
        wx.Frame.__init__(self, parent, id, title, pos, size)

class MyApp(wx.App):
"""Application class."""

    def OnInit(self):
        return True

def main():
    app = MyApp()
    try:
        with open('Tsukuyo.jpg'): pass
    except IOError:
        frame = MyFrame()
        frame.Show()
        dlg = wx.MessageDialog(frame, "Can not open image 'Tsukuyo.jpg'.",
                               "Error", wx.OK)
        dlg.ShowModal()
        dlg.Destroy()
        wx.Frame.Close(frame, True)
        app.ExitMainLoop()
        sys.exit(0)

    ## Nothing goes wrong? Show the picture.
    ## blah blah blah

Upvotes: 0

Views: 1068

Answers (1)

Mike Driscoll
Mike Driscoll

Reputation: 33111

This is a very oddly formatted piece of code. I suspect that wx.Frame.Close(frame, True) doesn't do what you expect. I've certainly never seen anyone close a frame like that. Normally you close the frame using the frame instance itself, which in this case would look like this:

frame.Close()

And that's all that's typically needed as well. I've never seen anyone use ExitMainLoop(). The sys.exit(0) is overkill. Once wx is done destroying all its widgets, it will exit. I suspect that one of these is doing something unexpected. Or it's possible that wx got the kill command and as it's trying to destroy itself, Python attempts to exit and it hangs.

So I re-wrote your code to follow the normal way of exiting a wx app:

import wx

class MyFrame(wx.Frame):
    """Frame class."""

    def  __init__(self, parent=None, id=-1,
                  pos=wx.DefaultPosition,
                  title='Hello, Tsukuyo!', size=(200,100)):
        """Create a Frame instanc."""
        wx.Frame.__init__(self, parent, id, title, pos, size)

        try:
            with open('Tsukuyo.jpg') as fh:
                data = fh.read()
        except IOError:
            dlg = wx.MessageDialog(self, "Can not open image 'Tsukuyo.jpg'.",
                                   "Error", wx.OK)
            dlg.ShowModal()
            dlg.Destroy()

            self.Close()

class MyApp(wx.App):
    """Application class."""

    def OnInit(self):
        frame = MyFrame()
        frame.Show()
        return True

def main():
    app = MyApp()

if __name__ == "__main__":
    main()

Upvotes: 1

Related Questions