2016-08-26 2 views
0

Si la taille d'un enfant dans un wx.BoxSizer change la boxsizer ne relayouted:Restructurer de wx.BoxSizer si l'enfant redimensionne

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

Après le clic sur le bouton gauche de ses changements de taille, mais la mise en page est cassé. After resizeing child

Si manuellement un relais sur un redimensionnement du bouton (ligne de commentaire), que d'obtenir une récursivité sans fin.

Dans mon cas d'utilisation réelle, je ne peux pas changer MyButton et MyButton est un wx.Panel qui change sur un événement que je ne peux pas déclencher.

Répondre

0

J'ai trouvé une solution propre. Si vous vérifiez les changements de taille dans le rappel d'événement avant de faire le relais, vous n'obtenez pas une récursivité sans fin:

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

Il ne fait pas partie de la conception wx.Sizer pour les modifications de taille afin de remonter automatiquement la hiérarchie de confinement pour refaire la mise en page. Au lieu de cela, vous devez déclencher le relais vous-même. C'est parce qu'il peut y avoir plusieurs changements qui se produisent et vous seul savez quand c'est le bon moment pour le faire. Si elle était automatisée, il serait trop facile de tomber dans une situation où un redimensionnement entraîne un autre redimensionnement qui entraîne un autre qui entraîne le redimensionnement du premier. Les calibreurs sont donc conçus pour effectuer une gestion descendante de la mise en page (par exemple, un redimensionnement de l'image provoque la position ou le redimensionnement des enfants du cadre) et lorsqu'il y a une situation où un changement ascendant doit se produire alors le programmeur doit l'aider d'une certaine manière. Dans votre exemple, vous pouvez simplement ajouter la ligne suivante à la méthode OnClick:

self.GetContainingSizer().Layout() 

Pour mises en page plus complexes alors quelque chose d'autre peut être nécessaire.