2016-08-26 2 views
0

Если размер детской в ​​wx.BoxSizer изменяет BoxSizer не relayouted:Relayout из wx.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() 

После щелчка на левой кнопке его размер изменяется, но расположение сломана. After resizeing child

Если ретрансляция вручную при изменении размера кнопки (строка комментария), чем получение бесконечной рекурсии.

В моем реальном случае использования я не могу изменить MyButton и MyButton - это wx.Panel, который изменяется на событие, на которое я не могу включить.

ответ

0

Я нашел собственное решение. Если вы проверите изменения размера в обратном вызове события перед выполнением ретрансляции, вы не получите бесконечную рекурсию:

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

Это не часть дизайна для изменения размера, чтобы автоматически перетекать вверх по иерархии сдерживания для повторной компоновки макета. Вместо этого вам нужно запустить ретранслятор самостоятельно. Это связано с тем, что возможны несколько изменений, и только вы знаете, когда это подходящее время для этого. Если бы это было автоматизировано, было бы слишком легко попасть в ситуацию, когда одно изменение размера вызывает другой размер, который вызывает другой, который заставляет первый изменить размер.

Таким образом, Sizer предназначены для управления макетом сверху вниз (например, изменение размера кадра приводит к положению или изменению размера дочерних элементов кадра), а также когда возникает ситуация, когда происходит изменение снизу вверх, тогда программист должен каким-то образом помочь ему. В вашем примере вы можете просто добавить следующую строку в метод OnClick:

self.GetContainingSizer().Layout() 

Для более сложных макетов, то еще что-то может потребоваться.

Смежные вопросы