微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

重置 wxPython 应用程序/销毁所有内容并从初始帧开始

如何解决重置 wxPython 应用程序/销毁所有内容并从初始帧开始

在这里阅读了其他答案,但它们似乎都只是完全关闭应用程序,确保所有进程和框架等都在此过程中被销毁。我想做的有点不同。

我的应用程序由三个框架(StartFrame、ParaFrame、ResultFrame)以及一个用于存储和操作数据的自定义类组成。基础知识是: StartFrame 只是一些文本和一个“开始”按钮。 “Start”创建一个 ParaFrame 实例,隐藏 StartFrame,并显示 ParaFrame 实例。 Paraframe 有一堆小部件供用户选择文件以及如何分析它。输入所有字段后,弹出“分析”按钮,(单击时)实例化自定义DataHandler 类,根据用户选择设置其参数,调用分析数据、隐藏自身和实例化的DataHandler 方法显示结果框架。毫不奇怪,ResultsFrame 显示了分析结果。

我想添加一个“重新开始”控件,它将销毁所有内容(所有框架、面板、DataHandler 实例等)并显示一个新的 StartFrame 实例,或者以其他方式销毁所有内容除了已经实例化但隐藏的 StartFrame,再次显示该帧,但我不知所措。

一个简化的例子如下:

import wx

class StartFrame(wx.Frame):
    """App start frame"""
    FRAME_MIN_SIZE = (900,600)
    def __init__(self,parent):
        wx.Frame.__init__(self,parent=parent,id=wx.ID_ANY,title="LOD Calculator",size=wx.Size(900,600),style=wx.CAPTION|wx.CLOSE_Box|wx.MINIMIZE_Box|wx.SYstem_MENU|wx.RESIZE_BORDER|wx.TAB_TRAVERSAL)

        self.startpnl = wx.Panel(self)

        self.startvsizer=wx.BoxSizer(wx.VERTICAL)
        self.startbtnsizer=wx.BoxSizer(wx.HORIZONTAL)

        self.btn = wx.Button(self.startpnl,wx.ID_ANY,"Start Analysis",\
         size = (200,60))
        self.btn.Bind(wx.EVT_BUTTON,self._OnStart)
        self.startbtnsizer.AddStretchSpacer()
        self.startbtnsizer.Add(self.btn,wx.CENTER)
        self.startbtnsizer.AddStretchSpacer()
        self.startvsizer.AddStretchSpacer()
        self.startvsizer.Add(self.startbtnsizer,wx.SizerFlags().Expand().Border(wx.ALL,25))
        self.startvsizer.AddStretchSpacer()
        self.startpnl.SetSizerAndFit(self.startvsizer)

    def _OnStart(self,event):
        self.frm2 = ParaFrame(None)
        self.Hide()
        self.frm2.Show()

class ParaFrame(wx.Frame):
    """Data load frame"""
    FRAME_MIN_SIZE = (950,800)
    def __init__(self,size=wx.Size(950,800),style=wx.CAPTION|wx.CLOSE_Box|wx.MINIMIZE_Box|wx.SYstem_MENU|wx.RESIZE_BORDER|wx.TAB_TRAVERSAL)

        self.mainpnl = wx.Panel(self)
        self.mainsizer = wx.BoxSizer(wx.HORIZONTAL)
        self.vsizer = wx.BoxSizer(wx.VERTICAL)

        self.analyzebtn = wx.Button(self.mainpnl,u"Analyze",\
         wx.DefaultPosition,wx.DefaultSize,0)
        self.vsizer.AddStretchSpacer()
        self.vsizer.Add(self.analyzebtn,wx.ALL,10)
        self.vsizer.AddStretchSpacer()
        self.mainsizer.AddStretchSpacer()
        self.mainsizer.Add(self.vsizer,25))
        self.mainsizer.AddStretchSpacer()
        self.mainpnl.SetSizerAndFit(self.mainsizer)

        self.analyzebtn.Bind(wx.EVT_BUTTON,self._analyze)

    def _analyze(self,event):
        dhandler = DataHandler(self)
        dhandler.data = "a bunch"
        dhandler.data2 = " of data"
        dhandler.data3 = " goes here"
        dhandler._analyzeData()
        self.resfrm = ResultFrame(self,dhandler.data,dhandler.data2)
        self.Hide()
        self.resfrm.Show()

class DataHandler:
    def __init__(self,parent):
        self.data = ''
        self.data2 = ''
        self.data3 = ''

    def _analyzeData(self):
        anastr = self.data + self.data2 + " gets analyzed"
        print(anastr)

class ResultFrame(wx.Frame):
    def __init__(self,parent,targets,dftables):
        super(ResultFrame,self).__init__(parent,title="results",size=(1535,935))
        self.targets = targets
        self.dftables = dftables
        self.InitUI()
        self.Layout()

    def InitUI(self):
        self.mainpnl = wx.Panel(self)
        self.mainsizer = wx.BoxSizer(wx.HORIZONTAL)
        self.vsizer = wx.BoxSizer(wx.VERTICAL)

        self.restartbtn = wx.Button(self.mainpnl,u"Start Over",0)
        self.vsizer.AddStretchSpacer()
        self.vsizer.Add(self.restartbtn,25))
        self.mainsizer.AddStretchSpacer()
        self.mainpnl.SetSizerAndFit(self.mainsizer)

        self.restartbtn.Bind(wx.EVT_BUTTON,self.OnRestart)

### this is where I try to destroy the ParaFrame instance and everything spawned by it,unsuccessfully
    def OnRestart(self,event):
        frm.frm2.Destroy()
        frm.Show()

def main():
    import wx.lib.mixins.inspection
    app = wx.App()
    frm = StartFrame(None)
    frm.Show()
    wx.lib.inspection.inspectionTool().Show(refreshTree=True)
    app.MainLoop()

if __name__ == "__main__":
    main()

如您所见,在 ResultFrame 中,我有一个“重新开始”按钮绑定到一个方法,在该方法中我尝试使用 {{1} },但得到一个错误

frm.frm2.Destroy()

如果我将行更改为仅 Traceback (most recent call last): File "C:\Python\Scripts\stackexchange code.py",line 102,in OnRestart frm.frm2.Destroy() NameError: name 'frm' is not defined ,我会收到相同的错误,但会显示 frm2.Destroy()

在这里做错了什么,我该如何实现我的目标?我对 OOP 还是个新手,对 wxPython 还是很陌生,所以任何帮助都非常感谢。我想要的只是让该按钮销毁所有内容并再次显示/初始 StartFrame。谢谢:)

解决方法

只要创建没有父类的每个类,就可以在创建链中的下一帧后使用 self.Destroy(),而不会破坏任何 children。 (传递任何需要的数据作为父级以外的参数)

所以你的代码看起来像这样:

import wx

class StartFrame(wx.Frame):
    """App start frame"""
    FRAME_MIN_SIZE = (900,600)
    def __init__(self,parent):
        wx.Frame.__init__(self,parent=parent,id=wx.ID_ANY,title="Load Calculator",size=wx.Size(900,600))

        self.startpnl = wx.Panel(self)

        self.startvsizer=wx.BoxSizer(wx.VERTICAL)
        self.startbtnsizer=wx.BoxSizer(wx.HORIZONTAL)

        self.btn = wx.Button(self.startpnl,wx.ID_ANY,"Start Analysis",\
         size = (200,60))
        self.btn.Bind(wx.EVT_BUTTON,self._OnStart)
        self.startbtnsizer.AddStretchSpacer()
        self.startbtnsizer.Add(self.btn,wx.CENTER)
        self.startbtnsizer.AddStretchSpacer()
        self.startvsizer.AddStretchSpacer()
        self.startvsizer.Add(self.startbtnsizer,wx.SizerFlags().Expand().Border(wx.ALL,25))
        self.startvsizer.AddStretchSpacer()
        self.startpnl.SetSizerAndFit(self.startvsizer)

    def _OnStart(self,event):
        frm2 = ParaFrame(None)
        frm2.Show()
        self.Destroy()

class ParaFrame(wx.Frame):
    """Data load frame"""
    FRAME_MIN_SIZE = (950,800)
    def __init__(self,600))

        self.mainpnl = wx.Panel(self)
        self.mainsizer = wx.BoxSizer(wx.HORIZONTAL)
        self.vsizer = wx.BoxSizer(wx.VERTICAL)

        self.analyzebtn = wx.Button(self.mainpnl,u"Analyze",\
         wx.DefaultPosition,wx.DefaultSize,0)
        self.vsizer.AddStretchSpacer()
        self.vsizer.Add(self.analyzebtn,wx.ALL,10)
        self.vsizer.AddStretchSpacer()
        self.mainsizer.AddStretchSpacer()
        self.mainsizer.Add(self.vsizer,25))
        self.mainsizer.AddStretchSpacer()
        self.mainpnl.SetSizerAndFit(self.mainsizer)

        self.analyzebtn.Bind(wx.EVT_BUTTON,self._analyze)

    def _analyze(self,event):
        dhandler = DataHandler(self)
        dhandler.data = "a bunch"
        dhandler.data2 = " of data"
        dhandler.data3 = " goes here"
        dhandler._analyzeData()
        resfrm = ResultFrame(None,dhandler.data,dhandler.data2)
        resfrm.Show()
        self.Destroy()

class DataHandler:
    def __init__(self,parent):
        self.data = ''
        self.data2 = ''
        self.data3 = ''

    def _analyzeData(self):
        anastr = self.data + self.data2 + " gets analyzed"
        print(anastr)

class ResultFrame(wx.Frame):
    def __init__(self,parent,targets,dftables):
        super(ResultFrame,self).__init__(parent,title="Results",size=(900,600))
        self.targets = targets
        self.dftables = dftables
        self.InitUI()
        self.Layout()

    def InitUI(self):
        self.mainpnl = wx.Panel(self)
        self.mainsizer = wx.BoxSizer(wx.HORIZONTAL)
        self.vsizer = wx.BoxSizer(wx.VERTICAL)

        self.restartbtn = wx.Button(self.mainpnl,u"Start Over",0)
        self.vsizer.AddStretchSpacer()
        self.vsizer.Add(self.restartbtn,25))
        self.mainsizer.AddStretchSpacer()
        self.mainpnl.SetSizerAndFit(self.mainsizer)

        self.restartbtn.Bind(wx.EVT_BUTTON,self.OnRestart)

### this is where I try to destroy the ParaFrame instance and everything spawned by it,unsuccessfully
    def OnRestart(self,event):
        frm = StartFrame(None)
        frm.Show()
        self.Destroy()

def main():
    app = wx.App()
    frm = StartFrame(None)
    frm.Show()
    app.MainLoop()

if __name__ == "__main__":
    main()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。