I'm new to Python and this week I'm trying to use wxPython module to create GUIs. I think I understood how use sizers, but what happened to this code is intriguing me. Can someone help me to understand why?
This code should create a child panel for toolbar purposes and some content after it:
import wx
class Main_window (wx.Frame):
def __init__(self):
super(Main_window, self).__init__(parent = None, title = 'Some App')
main_panel = wx.Panel(self)
main_panel_sizer = wx.BoxSizer(wx.VERTICAL)
# Calling panels
toolbar = ToolBar(self)
main_panel_sizer.Add(toolbar, 1, wx.EXPAND)
button1 = wx.Button(main_panel, label='Button 1')
main_panel_sizer.Add(button1, 0, wx.ALL|wx.ALIGN_LEFT)
text = wx.StaticText(main_panel, label = 'Text 1')
main_panel_sizer.Add(text, wx.ALL|wx.ALIGN_LEFT)
# Final lines of constructor
main_panel.SetSizer(main_panel_sizer)
self.Show()
class ToolBar (wx.Panel):
def __init__(self, parent):
super().__init__(parent)
self.SetBackgroundColour('blue')
toolbar_sizer = wx.BoxSizer(wx.HORIZONTAL)
button2 = wx.Button(self, label = 'Button 2')
toolbar_sizer.Add(button2, 0, wx.ALIGN_LEFT)
self.SetSizer(toolbar_sizer)
if __name__ == '__main__':
app = wx.App()
frame = Main_window()
app.MainLoop()
But the ouput is a mess. Child panel, text and buttons are stacked in top. But if I comment the Toolbar calling:
import wx
class Main_window (wx.Frame):
def __init__(self):
super(Main_window, self).__init__(parent = None, title = 'Some App')
main_panel = wx.Panel(self)
main_panel_sizer = wx.BoxSizer(wx.VERTICAL)
# Calling panels
# toolbar = ToolBar(self)
# main_panel_sizer.Add(toolbar, 1, wx.EXPAND)
button1 = wx.Button(main_panel, label='Button 1')
main_panel_sizer.Add(button1, 0, wx.ALL|wx.ALIGN_LEFT)
text = wx.StaticText(main_panel, label = 'Text 1')
main_panel_sizer.Add(text, wx.ALL|wx.ALIGN_LEFT)
# Final lines of constructor
main_panel.SetSizer(main_panel_sizer)
self.Show()
class ToolBar (wx.Panel):
def __init__(self, parent):
super().__init__(parent)
self.SetBackgroundColour('blue')
toolbar_sizer = wx.BoxSizer(wx.HORIZONTAL)
button2 = wx.Button(self, label = 'Button 2')
toolbar_sizer.Add(button2, 0, wx.ALIGN_LEFT)
self.SetSizer(toolbar_sizer)
if __name__ == '__main__':
app = wx.App()
frame = Main_window()
app.MainLoop()
The sizer works again as it should. Someone can explain this? Seems witchcraft.
Thanks at advance.
Roughly speaking, you didn't apply the sizer to Main_window and ToolBar is a standalone panel.
Below I assign a sizer to self and put into it the main_panel and toolbar, which both have their own sizers.
Hope that clears things up. (Hint: it's not magic - well actually it is, courtesy of Mr Robin Dunn) :)
import wx
class Main_window (wx.Frame):
def __init__(self):
super(Main_window, self).__init__(parent = None, title = 'Some App')
main_panel = wx.Panel(self)
main_panel_sizer = wx.BoxSizer(wx.VERTICAL)
main_sizer = wx.BoxSizer(wx.VERTICAL)
# Calling panels
toolbar = ToolBar(self)
button1 = wx.Button(main_panel, label='Button 1')
main_panel_sizer.Add(button1, 0, wx.ALL|wx.ALIGN_LEFT)
text = wx.StaticText(main_panel, label = 'Text 1')
main_panel_sizer.Add(text, wx.ALL|wx.ALIGN_LEFT)
main_panel.SetSizer(main_panel_sizer)
main_sizer.Add(toolbar, 1, wx.EXPAND)
main_sizer.Add(main_panel)
# Final lines of constructor
self.SetSizer(main_sizer)
self.Show()
class ToolBar (wx.Panel):
def __init__(self, parent):
super().__init__(parent)
self.SetBackgroundColour('blue')
toolbar_sizer = wx.BoxSizer(wx.HORIZONTAL)
button2 = wx.Button(self, label = 'Button 2')
toolbar_sizer.Add(button2, 0, wx.ALIGN_LEFT)
self.SetSizer(toolbar_sizer)
if __name__ == '__main__':
app = wx.App()
frame = Main_window()
app.MainLoop()