wxpython

Import 2 wx windows from each other


Imagine that we have 1.py and 2.py as a main window and a sub window, and we want to create a button to navigate between them. For an explanation of the idea see the code: 1.py (the main window):

import wx

class app(wx.Frame):
    def __init__(self, parent):
        super(app,self).__init__(parent,-1, title= 'example app')
        p = wx.Panel(self,-1)
        self.Center()
        self.btn = wx.Button(p,-1, 'go')
        self.btn.Bind(wx.EVT_BUTTON, self.onBtn)
        self.Show()

    def onBtn(self, event):
        # I need the code to import the 2.py's class.

app = wx.App()
school(None)
app.MainLoop()

2.py (the sub window):

import wx

class appTwo(wx.Frame):
    def __init__(self, parent):
        super(appTwo,self).__init__(parent,-1, title= 'example app')
        p = wx.Panel(self,-1)
        self.Center()
        self.btn = wx.Button(p,-1, 'back')
        self.btn.Bind(wx.EVT_BUTTON, self.onBtn)
        self.Show()

    def onBtn(self, event):
        # I need the code to import the 1.py's class.

app = wx.App()
app2(None)
app.MainLoop()

Solution

  • In this example I have defined two panels (not Frames) and you can switch between them. The button events are handled in the Frame and not in the individual panels

    import wx
    
    class MainFrame(wx.Frame):
        def __init__(self, *args, **kwargs):
            super().__init__(None, *args, **kwargs)
            self.Title = 'Wx App'
    
            self.panel_one = MainPanel(self)
            self.sizer = wx.BoxSizer(wx.VERTICAL)
            self.sizer.Add(self.panel_one)
            self.SetSizerAndFit(self.sizer)
            self.Center()
            self.Show()
    
        def onBtn_one(self, event):
            self._clear_sizer()
            self.panel_two = SecondPanel(self)
            self.sizer.Add(self.panel_two)
    
        def onBtn_two(self, event):
            self._clear_sizer()
            self.panel_one = MainPanel(self)
            self.sizer.Add(self.panel_one)
    
        def _clear_sizer(self):
            for child in self.sizer.GetChildren():
                if child.IsSizer():
                    if child.IsSizer():
                        self._clear_sizer(child.GetSizer())
                else:
                    child.GetWindow().Destroy()
            self.sizer.Clear()
    
    
    class MainPanel(wx.Panel):
        def __init__(self, parent, *args, **kwargs):
            super().__init__(parent, *args, **kwargs)
    
            txt_info = wx.StaticText(self, label='panel 1')
            btn = wx.Button(self, -1, 'go to 2')
            btn.Bind(wx.EVT_BUTTON, parent.onBtn_one)
    
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(txt_info)
            sizer.Add(btn)
            self.SetSizerAndFit(sizer)
    
    
    class SecondPanel(wx.Panel):
        def __init__(self, parent, *args, **kwargs):
            super().__init__(parent, *args, **kwargs)
    
            txt_info = wx.StaticText(self, label='panel 2')
            btn = wx.Button(self,-1, 'go to 1')
            btn.Bind(wx.EVT_BUTTON, parent.onBtn_two)
    
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(txt_info)
            sizer.Add(btn)
            self.SetSizerAndFit(sizer)
    
    
    if __name__ == '__main__':
        wx_app = wx.App()
        MainFrame()
        wx_app.MainLoop()