Search code examples
python-2.7wxpythonboxsizer

Relayout of wx.BoxSizer if child resizes


If the size of a children in a wx.BoxSizer changes the boxsizer is not relayouted:

import wx

class MyButton(wx.Button):
    def __init__(self, parent):
        wx.Button.__init__(self, parent, -1, style=wx.SUNKEN_BORDER, label="ABC")
        self.Bind(wx.EVT_BUTTON, self.OnClick)

    def OnClick(self, event):
        self.SetSize((200, 200))
        self.SetSizeHints(200, 200)

class MyFrame(wx.Frame):
    def __init__(self, parent, ID, title):
       wx.Frame.__init__(self, parent, ID, title, size=(300, 250))

       self.button = MyButton(self)
       button2 = wx.Button(self, -1, style=wx.SUNKEN_BORDER, label="DEF")

       # self.button.Bind(wx.EVT_SIZE, self.OnButtonResize)

       box = wx.BoxSizer(wx.HORIZONTAL)
       box.Add(self.button, 1, wx.EXPAND)
       box.Add(button2, 1, wx.EXPAND)

       self.SetAutoLayout(True)
       self.SetSizer(box)
       self.Layout()

    def OnButtonResize(self, event):
        event.Skip()
        self.Layout()

app = wx.App()
frame = MyFrame(None, -1, "Sizer Test")
frame.Show()
app.MainLoop()

After the click on the left button his size changes, but layout is broken. After resizeing child

If a manually relayout on a resize of the button (comment line), than a get a endless recursion.

In my real use case I can't change MyButton and MyButton is a wx.Panel which changes on an event I can't trigger on.


Solution

  • I found a own solution. If you check for size changes in the event callback before doing the relayout, you don't get a endless recursion:

    class MyFrame(wx.Frame):
        def __init__(self, parent, ID, title):
           wx.Frame.__init__(self, parent, ID, title, size=(300, 250))
    
           self.button = MyButton(self)
           button2 = wx.Button(self, -1, style=wx.SUNKEN_BORDER, label="DEF")
    
           self.button.Bind(wx.EVT_SIZE, self.OnButtonResize)
    
           box = wx.BoxSizer(wx.HORIZONTAL)
           box.Add(self.button, 1, wx.EXPAND)
           box.Add(button2, 1, wx.EXPAND)
    
           self.buttonSize = None
           self.SetSizer(box)
           self.Layout()
    
        def OnButtonResize(self, event):
            event.Skip()
    
            if self.buttonSize != event.Size:
                self.buttonSize = event.Size
                self.Layout()