Why does this wxPython GUI freeze when self.Destroy() is used instead of self.Close()? (example attached)

China☆狼群 提交于 2019-12-20 07:47:43

问题


LoginDialog is opened with self.loginButton, and upon closing it, the GUI freezes; the login button remains pressed, and there are only alert sounds when attempting to click on anything.

LoginDialog() was from this tutorial, just augmented with the file-write line in onLogin (which isn't the problem source). All appears to work when switching from self.Destroy() to self.Close().

wxPython version is 3.0, Python 2.7.10

The following code is a working example of the issue:

import wx

# wxGlade dependency
import gettext

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        wx.Frame.__init__(self, *args, **kwds)

        self.updateLoginButton = wx.Button(self, wx.ID_ANY, _("Store/Update Login"))

        self.Bind(wx.EVT_BUTTON, self.updateLogin, self.updateLoginButton)

        self.__set_properties()
        self.__do_layout()

    def __set_properties(self):
        self.SetTitle(_("Dialog Test"))

    def __do_layout(self):
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        grid_sizer_1 = wx.FlexGridSizer(3, 1, 1, 0)

        exportButtons_sizer = wx.FlexGridSizer(1, 1, 1, 10)
        exportButtons_sizer.Add(self.updateLoginButton, 0, wx.TOP | wx.ALIGN_CENTER, 15)

        grid_sizer_1.Add(exportButtons_sizer, 0, wx.TOP | wx.ALIGN_CENTER, 20)

        sizer_1.Add(grid_sizer_1, 1, wx.ALL | wx.EXPAND, 15)

        self.SetSizer(sizer_1)
        sizer_1.Fit(self)
        self.Layout()

    def updateLogin(self, event):
        dlg = LoginDialog(self, -1)
        dlg.ShowModal()

class MyApp(wx.App):
    def OnInit(self):
        frame_1 = MyFrame(None, wx.ID_ANY, "")
        self.SetTopWindow(frame_1)
        frame_1.Show()
        return True

class LoginDialog(wx.Dialog):
    """
    Class to define login dialog
    """

    # ----------------------------------------------------------------------
    def __init__(self, parent, id, title="Update Login Info"):
        """Constructor"""
        wx.Dialog.__init__(self, parent, id, title)

        # user info
        user_sizer = wx.BoxSizer(wx.HORIZONTAL)

        user_lbl = wx.StaticText(self, label="Username:")
        user_sizer.Add(user_lbl, 0, wx.ALL | wx.CENTER, 5)
        self.user = wx.TextCtrl(self)
        user_sizer.Add(self.user, 0, wx.ALL, 5)

        # pass info
        p_sizer = wx.BoxSizer(wx.HORIZONTAL)

        p_lbl = wx.StaticText(self, label="Password:")
        p_sizer.Add(p_lbl, 0, wx.ALL | wx.CENTER, 5)
        self.password = wx.TextCtrl(self, style=wx.TE_PASSWORD | wx.TE_PROCESS_ENTER)
        p_sizer.Add(self.password, 0, wx.ALL, 5)

        main_sizer = wx.BoxSizer(wx.VERTICAL)
        main_sizer.Add(user_sizer, 0, wx.ALL, 5)
        main_sizer.Add(p_sizer, 0, wx.ALL, 5)

        btn = wx.Button(self, label="OK")
        btn.Bind(wx.EVT_BUTTON, self.onLogin)
        main_sizer.Add(btn, 0, wx.ALL | wx.CENTER, 5)

        self.SetSizer(main_sizer)

        self.__set_properties()

    # ----------------------------------------------------------------------
    def onLogin(self, event):
        """
        Check credentials and login
        """
        password = self.password.GetValue()
        email = self.user.GetValue()

        with open('login.txt', 'w') as f:
            f.write(email + ', ' + password)

        self.Destroy()

    def __set_properties(self):
        self.user.SetMinSize((220, 20))


if __name__ == "__main__":
    gettext.install("app")

    app = MyApp(0)
    app.MainLoop()

回答1:


If a dialog is intended to be used with ShowModal dialog then the dialog should call EndModal when it is done, and the caller should be the one who calls Destroy after it has fetched values from the dialog if needed.



来源:https://stackoverflow.com/questions/41084112/why-does-this-wxpython-gui-freeze-when-self-destroy-is-used-instead-of-self-cl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!