Python 2.7 如果子级调整大小,则重新显示wx.BoxSizer

Python 2.7 如果子级调整大小,则重新显示wx.BoxSizer,python-2.7,wxpython,boxsizer,Python 2.7,Wxpython,Boxsizer,如果wx.BoxSizer中的子项大小发生变化,则不会重新显示BoxSizer: 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 O

如果
wx.BoxSizer
中的子项大小发生变化,则不会重新显示BoxSizer:

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()
点击左键后,他的尺寸改变,但布局被破坏。

如果手动重新显示一个调整大小的按钮(注释行),那么就会得到一个无休止的递归


在我的实际用例中,我无法更改
MyButton
MyButton
是一个
wx.Panel
,它在我无法触发的事件中发生更改。

它不是
wx.Sizer
设计的一部分,用于大小更改自动向上流动到容器层次结构中,以便重做布局。相反,你需要自己触发重播。这是因为可能会发生多个更改,只有您知道何时是进行更改的好时机。如果它是自动化的,那么很容易陷入这样一种情况:一个调整会导致另一个调整,而另一个调整又会导致第一个调整

因此,大小调整器被设计为执行自顶向下的布局管理(例如,框架调整会导致框架子对象的位置或大小调整),当需要进行自下而上的更改时,程序员需要以某种方式提供帮助。在您的示例中,只需将以下行添加到
OnClick
方法:

self.GetContainingSizer().Layout()

对于更复杂的布局,则可能需要其他东西。

它不是用于尺寸更改的
wx.Sizer
设计的一部分,以自动向上流动到安全壳层次结构以重新进行布局。相反,你需要自己触发重播。这是因为可能会发生多个更改,只有您知道何时是进行更改的好时机。如果它是自动化的,那么很容易陷入这样一种情况:一个调整会导致另一个调整,而另一个调整又会导致第一个调整

因此,大小调整器被设计为执行自顶向下的布局管理(例如,框架调整会导致框架子对象的位置或大小调整),当需要进行自下而上的更改时,程序员需要以某种方式提供帮助。在您的示例中,只需将以下行添加到
OnClick
方法:

self.GetContainingSizer().Layout()

对于更复杂的布局,则可能需要其他东西。

我找到了自己的解决方案。如果在执行重新播放之前检查事件回调中的大小更改,则不会得到无休止的递归:

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()

我找到了自己的解决办法。如果在执行重新播放之前检查事件回调中的大小更改,则不会得到无休止的递归:

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()