Search code examples
pythonwxpython

wxNotebook and wxBoxSizer behaviour


I have a GUI with two wxNotebook-elements like this:

class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, 
                          "My App",size=(800,600),pos=((wx.DisplaySize()[0]-800)/2,(wx.DisplaySize()[1]-600)/2),style= wx.SYSTEM_MENU | wx.CAPTION | wx.MINIMIZE_BOX | wx.CLOSE_BOX)

        self.SetBackgroundColour((232,232,232))
        self.p = wx.Panel(self,size=(800,6300),pos=(0,0))
        self.SetPages()

    def SetPages(self):
        self.nb = wx.Notebook(self.p,style=wx.NB_BOTTOM)
        page1 = PageOne(self.nb)
        page2 = PageTwo(self.nb)
        self.nb.AddPage(page1, "page1")
        self.nb.AddPage(page2, "page2")
        self.sizer = wx.BoxSizer()
        self.sizer.Add(self.nb, 1, wx.EXPAND)
        self.p.SetSizer(self.sizer)

Now I want to create a third Notebook-page & set focus on it at a certain event. But this does not work:

def CreateNewPageEvent(self, event):
    self.CreateNewPage()

def CreateNewPage(self):
    page3 = PageThree(self.nb)
    self.nb.AddPage(page3, "page3")

I must admit that I'm not sure what a "BoxSizer" does =/ Any ideas to get this working?

Edit: OK, this works for an event inside my MainFrame-class. But I also want to create a new nb-page from an event of another class:

class ContinueApp(MainFrame):
    def foo(self):
        super(ContinueApp, self).CreateNewPage()

def continueapp(event):
    cont = ContinueApp()
    cont.foo()

Solution

  • The BoxSizer (and other sizers) are for laying out widgets so you don't have to position them yourself. They also help control which widgets expand or stretch when you make your application window larger or smaller. In your case, you should NOT add the same widget to the same sizer twice. You shouldn't add one widget to two different sizers either.

    You need to remove this:

    self.nb.AddPage(page1, "page3")
    self.sizer.Add(self.nb, 1, wx.EXPAND)
    self.p.SetSizer(self.sizer)
    

    Also note that you are adding page1 to the notebook again when you should be adding page3:

    page3 = PageThree(self.nb)
    self.nb.AddPage(page3, "page3")
    

    If you want to switch between tabs programmatically, you should use the notebook's SetSelection method. I have an example app you can look at in the following tutorial (or the answer below it):

    Once you have switched tabs, you may want to set the focus on a widget within that tab. I find that using pubsub to send events is probably the cleanest way to communicate between classes. I have a couple of tutorials on that subject: