如何在wxPython GUI中使用BoxSizers实现整齐布局
在 wxPython 中,BoxSizer
是一种常用的布局管理器,可以用来将窗口控件垂直或水平排列,从而实现整齐的布局。BoxSizer
分为 wx.BoxSizer(wx.HORIZONTAL)
和 wx.BoxSizer(wx.VERTICAL)
两种,分别用于水平和垂直布局。
1、问题背景
在开发一个wxPython GUI应用程序时,我遇到一个问题,希望实现如下布局:
labelOne | inputOne
lblTwo | inputTwo
lblThree | inputThree
其中,文本标签左对齐,输入框全部对齐。我在wxPython演示代码中看到了这种布局,但是它们都使用了FlexGridSizer,而我只想使用BoxSizers。原因是BoxSizers更简单,而且我对任何类型的Sizers都知之甚少。我尝试过将输入和文本放在两个垂直的Sizers中,然后将它们放入一个水平的Sizers,但这样做不起作用,因为文本与输入框不一致。我还尝试过这样做,并且还将每个文本和输入配对放在一个Sizer中,结果更糟。有什么建议吗?
2、解决方案
以下是一个使用BoxSizers实现上述布局的简单示例:
import wxclass MyForm(wx.Frame):def __init__(self):wx.Frame.__init__(self, None, wx.ID_ANY, "Tutorial")# Add a panel so it looks the correct on all platformspanel = wx.Panel(self, wx.ID_ANY)# create the labelslblOne = wx.StaticText(panel, label="labelOne", size=(60,-1))lblTwo = wx.StaticText(panel, label="lblTwo", size=(60,-1))lblThree = wx.StaticText(panel, label="lblThree", size=(60,-1))# create the text controlstxtOne = wx.TextCtrl(panel)txtTwo = wx.TextCtrl(panel)txtThree = wx.TextCtrl(panel)# create some sizersmainSizer = wx.BoxSizer(wx.VERTICAL)lineOneSizer = wx.BoxSizer(wx.HORIZONTAL)lineTwoSizer = wx.BoxSizer(wx.HORIZONTAL)lineThreeSizer = wx.BoxSizer(wx.HORIZONTAL)# add widgets to sizerslineOneSizer.Add(lblOne, 0, wx.ALL|wx.ALIGN_LEFT, 5)lineOneSizer.Add(txtOne, 0, wx.ALL, 5)lineTwoSizer.Add(lblTwo, 0, wx.ALL|wx.ALIGN_LEFT, 5)lineTwoSizer.Add(txtTwo, 0, wx.ALL, 5)lineThreeSizer.Add(lblThree, 0, wx.ALL|wx.ALIGN_LEFT, 5)lineThreeSizer.Add(txtThree, 0, wx.ALL, 5)mainSizer.Add(lineOneSizer)mainSizer.Add(lineTwoSizer)mainSizer.Add(lineThreeSizer)panel.SetSizer(mainSizer)# Run the program
if __name__ == "__main__":app = wx.App(False)frame = MyForm()frame.Show()app.MainLoop()
这是一种实现上述布局的方法,但它有些混乱。以下是一个经过重构的版本:
import wxclass MyForm(wx.Frame):def __init__(self):wx.Frame.__init__(self, None, wx.ID_ANY, "Tutorial")# create the main sizerself.mainSizer = wx.BoxSizer(wx.VERTICAL)# Add a panel so it looks the correct on all platformsself.panel = wx.Panel(self, wx.ID_ANY)lbls = ["labelOne", "lblTwo", "lblThree"]for lbl in lbls:self.buildLayout(lbl)self.panel.SetSizer(self.mainSizer)#----------------------------------------------------------------------def buildLayout(self, text):""""""lblSize = (60,-1)lbl = wx.StaticText(self.panel, label=text, size=lblSize)txt = wx.TextCtrl(self.panel)sizer = wx.BoxSizer(wx.HORIZONTAL)sizer.Add(lbl, 0, wx.ALL|wx.ALIGN_LEFT, 5)sizer.Add(txt, 0, wx.ALL, 5)self.mainSizer.Add(sizer)# Run the program
if __name__ == "__main__":app = wx.App(False)frame = MyForm()frame.Show()app.MainLoop()
对于大多数布局,除了最基本的布局之外,我们通常无法避免使用多种类型的Sizers才能实现我们的设计。这里有一个关于Sizers的很好教程。