wxPython:动态内容下wx.CollapsiblePane布局适配异常求助
解决wx.CollapsiblePane添加内容后无法自动适配布局的问题
问题核心在于wx.CollapsiblePane在展开状态下,不会自动感知内部面板的内容变化并更新自身尺寸。手动折叠再展开能恢复正常,是因为该动作会强制重新计算面板尺寸。
解决方案
在添加新步骤后,需要依次完成以下操作:
- 让内部面板的sizer重新布局
- 让内部面板适配其内容尺寸
- 通知父容器的sizer重新布局,从而让
CollapsiblePane更新自身尺寸
修改onAddStepButton方法如下:
def onAddStepButton(self, _ = None): newSizer = self.MakeStepUI() self.StepsSizer.Insert(self.StepsSizer.GetItemCount()-1, newSizer, 0, wx.EXPAND|wx.ALL, 10) pane = self.GetPane() self.StepsSizer.Layout() # 重新布局内部sizer pane.Fit() # 让内部面板适配内容 self.GetParent().Layout() # 通知父容器更新布局
完整修改后的代码
#!/usr/bin/env python3 import wx class StepsPane(wx.CollapsiblePane): def __init__(self, parent): wx.CollapsiblePane.__init__(self, parent, label = 'Test Pane') pane = self.GetPane() self.StepsSizer = wx.BoxSizer(wx.VERTICAL) AddBindStepButton = wx.Button(pane, -1, "Add Step...") AddBindStepButton.Bind(wx.EVT_BUTTON, self.onAddStepButton) self.StepsSizer.Add(AddBindStepButton, 0, wx.TOP, 10) self.onAddStepButton() # Add a step 1. pane.SetSizer(self.StepsSizer) def onAddStepButton(self, _ = None): newSizer = self.MakeStepUI() self.StepsSizer.Insert(self.StepsSizer.GetItemCount()-1, newSizer, 0, wx.EXPAND|wx.ALL, 10) pane = self.GetPane() self.StepsSizer.Layout() pane.Fit() self.GetParent().Layout() def MakeStepUI(self): parent = self.GetPane() stepNumber = self.StepsSizer.GetItemCount() sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(wx.StaticText(parent, -1, f"Step {stepNumber}:"), 0, wx.ALIGN_CENTER_VERTICAL) sizer.Add(wx.TextCtrl(parent), 1) sizer.Add(wx.Button(parent), 0) return sizer class Main(wx.Frame): def __init__(self, parent): wx.Frame.__init__(self, parent) self.Sizer = wx.BoxSizer(wx.VERTICAL) # this is here to simulate other content in the full app that will make the window wider self.Sizer.Add(wx.StaticText(self, -1, label = "(other content)", size = (500,20)), 0, wx.EXPAND|wx.ALL, 10) sp = StepsPane(self) self.Sizer.Add(sp, 1, wx.EXPAND|wx.ALL, 5) sp.Expand() self.SetSizer(self.Sizer) class MyApp(wx.App): def OnInit(self): self.Main = Main(None) self.Main.Show() return True if __name__ == "__main__": app = MyApp(redirect=False) app.MainLoop()
原理说明
pane.Fit()会让内部面板根据sizer的计算结果调整自身尺寸,确保所有内容都能显示self.GetParent().Layout()会触发父容器的sizer重新计算布局,让CollapsiblePane在展开状态下更新到正确的高度,同时因为父sizer中CollapsiblePane设置了wx.EXPAND,横向会保持与父容器一致的宽度,不会压缩TextCtrl
内容的提问来源于stack exchange,提问作者emerson
相关产品推荐
相关产品推荐

