Search code examples
pythonpython-2.7user-interfacewxpython

Buttons under wx.Notebook element


I'm trying to add Save/Cancel buttons under wx.Notebook element, however after adding this buttons on wx.Frame all my UI was broken. For example, piece of my wx.Notebook element is see at the upper left corner. But with button all OK. How I can fix this, that my UI hasn't been violated?

# -*- coding: utf-8 -*-
import wx

ID_NOTEBOOK_CTRL = 2000
ID_BUTTON_SAVE = 2001
ID_BUTTON_CANCEL_SAVE = 2002
ID_TAB_ONE = 2003
ID_TAB_ONE_CRYPTO_CHECKBOX = 2004    

class TabPanelBasics(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent=parent, id=ID_TAB_ONE)

        self.LabelCrypto = wx.StaticText(self, label='Crypto:', pos=(15, 15))

        crypto = ['AES-256', 'RC5', 'Twofish']
        self.ComboBox = wx.ComboBox(self, choices=crypto, style=wx.CB_READONLY, pos=(160, 10))    

class NotebookCtrl(wx.Notebook):
    def __init__(self, parent):
        wx.Notebook.__init__(self, parent, id=ID_NOTEBOOK_CTRL, style=wx.BK_DEFAULT)

        self.tabBasicPreferences = TabPanelBasics(self)
        self.AddPage(self.tabBasicPreferences, "Test1")
        self.testTab = TabPanelBasics(self)
        self.AddPage(self.testTab, "Test2")    

        self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
        self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGING, self.OnPageChanging)

    def OnPageChanged(self, event):
        old = event.GetOldSelection()
        new = event.GetSelection()
        sel = self.GetSelection()
        event.Skip()

    def OnPageChanging(self, event):
        old = event.GetOldSelection()
        new = event.GetSelection()
        sel = self.GetSelection()
        event.Skip()

class OptionsCtrl(wx.Frame):
    """
        Frame that holds all other widgets
    """
    def __init__(self, parent, id, title, ico_folder):
        wx.Frame.__init__(self, parent, -1, title, style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER)
        self.panel = wx.Panel(self)

        self.notebook = NotebookCtrl(self.panel)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.notebook, 1, wx.ALL | wx.EXPAND, 5)

        self.accept_button = wx.Button(self, id=ID_BUTTON_SAVE, label='Save', pos=(210, 215))
        self.cancel_button = wx.Button(self, id=ID_BUTTON_CANCEL_SAVE, label='Cancel', pos=(305, 215))

        self.Bind(wx.EVT_BUTTON, self.CloseOptionsWindowAndSave, id=ID_BUTTON_SAVE)
        self.Bind(wx.EVT_BUTTON, self.CloseOptionsWindow, id=ID_BUTTON_CANCEL_SAVE)

        self.panel.SetSizer(self.sizer)
        self.Layout()

        self.icon = wx.Icon(ico_folder+'/icons/app.ico', wx.BITMAP_TYPE_ICO)
        self.SetIcon(self.icon)

    def CloseOptionsWindowAndSave(self, event):
        print 'saving...'
        self.Close()

    def CloseOptionsWindow(self, event):
        print 'close without save!'
        self.Close()    

if __name__ == "__main__":
    app = wx.App(0)
    ico_folder = '..'
    frame = OptionsCtrl(None, -1, 'Options', ico_folder)
    frame.Show()
    app.MainLoop()

Solution

  • The notebook's parent is self.panel while the buttons' parent is the frame. This is your problem. Set each of the button's parent to self.panel and it should work, assuming you have the positioning set up correctly.

    Personally, I would put the buttons into a Horizontal boxsizer and then add that sizer to self.sizer instead of using absolute positioning.