import wx
class MyFrame(wx.Frame):
def __init__(self, parent):
self.parent = parent
super(MyFrame, self).__init__(parent, -1, 'Test')
# create a base panel
self.panel = wx.Panel(self)
self.panel.SetBackgroundColour('blue')
vbox = wx.BoxSizer(wx.VERTICAL)
# create a sub-panel 1.
self.panel_1 = wx.Panel(self.panel, -1)
self.panel_1.SetBackgroundColour('yellow')
vbox.Add(self.panel_1, 1, wx.EXPAND)
# create a sub-panel 2.
self.panel_2 = wx.Panel(self.panel, -1)
self.panel_2.SetBackgroundColour('pink')
vbox.Add(self.panel_2, 1, wx.EXPAND)
# This line of code cause the problem!
self.panel.Bind(wx.EVT_SIZE, self._on_paint)
self.panel.SetSizer(vbox)
self.Show()
def _on_paint(self, e):
pass
app = wx.App()
frame = MyFrame(None)
app.MainLoop()
The script above don't produce the ideal output where two sub-panel should be equal in size and occupy all of the frame together.
The ideal output can be attained by delete:
self.panel.Bind(wx.EVT_SIZE, self._on_paint)
I also have tested that the script work properly if it is wx.EVT_PAINT rather than wx.EVT_SIZE.
So, why the line above cause sizer not work properly?
Because the default EVT_SIZE
handler in the base class is where the automatic layout using the sizer is performed. By intercepting the EVT_SIZE
event with your own handler you are preventing that default functionality.
You can either call e.Skip()
in your handler so the event processing system will continue looking for matching event handlers after yours is done, or you can add code like the following to your handler so the layout algorithm will still be performed:
window = e.GetEventObject()
if window.GetAutoLayout():
window.Layout()