wxPython中的布局管理
最后修改于 2023 年 1 月 10 日
一个典型的应用程序由各种小部件组成。这些小部件放置在容器小部件内。程序员必须管理应用程序的布局。 这不是一项容易的任务。 在 wxPython 中,可以使用绝对定位或使用 sizer 来布局小部件。
绝对定位
程序员以像素为单位指定每个小部件的位置和大小。 绝对定位有几个缺点
- 如果我们调整窗口大小,小部件的大小和位置不会改变。
- 应用程序在各个平台上的外观不同。
- 更改应用程序中的字体可能会破坏布局。
- 如果我们决定更改我们的布局,我们必须完全重做我们的布局,这既乏味又耗时。
可能存在我们可以使用绝对定位的情况。 例如,小型测试示例。 但大多数情况下,在现实世界的程序中,程序员使用 sizer。
在我们的示例中,我们有一个文本编辑器的简单框架。 如果我们调整窗口大小,我们的 wx.TextCtrl
的大小不会像我们期望的那样改变。
#!/usr/bin/env python """ ZetCode wxPython tutorial In this example, we lay out widgets using absolute positioning. author: Jan Bodnar website: www.zetcode.com last modified: July 2020 """ import wx class Example(wx.Frame): def __init__(self, parent, title): super(Example, self).__init__(parent, title=title, size=(350, 300)) self.InitUI() self.Centre() def InitUI(self): self.panel = wx.Panel(self) self.panel.SetBackgroundColour("gray") self.LoadImages() self.mincol.SetPosition((20, 20)) self.bardejov.SetPosition((40, 160)) self.rotunda.SetPosition((170, 50)) def LoadImages(self): self.mincol = wx.StaticBitmap(self.panel, wx.ID_ANY, wx.Bitmap("mincol.jpg", wx.BITMAP_TYPE_ANY)) self.bardejov = wx.StaticBitmap(self.panel, wx.ID_ANY, wx.Bitmap("bardejov.jpg", wx.BITMAP_TYPE_ANY)) self.rotunda = wx.StaticBitmap(self.panel, wx.ID_ANY, wx.Bitmap("rotunda.jpg", wx.BITMAP_TYPE_ANY)) def main(): app = wx.App() ex = Example(None, title='Absolute positioning') ex.Show() app.MainLoop() if __name__ == '__main__': main()
在上面的例子中,我们使用绝对坐标定位了三个图像。
self.mincol.SetPosition((20, 20))
使用 SetPosition()
方法,我们将图像放置在 x=20, y=20 坐标处。

使用 sizer
Sizer 确实解决了我们通过绝对定位提到的所有这些问题。 wxPython 有以下 sizer
- wx.BoxSizer
- wx.StaticBoxSizer
- wx.GridSizer
- wx.FlexGridSizer
- wx.GridBagSizer
wx.BoxSizer
wx.BoxSizer
允许我们将几个小部件放入一行或一列中。 我们可以将另一个 sizer 放入一个现有的 sizer 中。 通过这种方式,我们可以创建非常复杂的布局。
box = wx.BoxSizer(integer orient) box.Add(wx.Window window, integer proportion=0, integer flag = 0, integer border = 0)
方向可以是 wx.VERTICAL
或 wx.HORIZONTAL
。 通过 Add()
方法将小部件添加到 wx.BoxSizer
中。 为了理解它,我们需要查看它的参数。
比例参数定义了小部件在定义的方向上如何变化的比例。 假设我们有三个比例分别为 0、1 和 2 的按钮。 它们被添加到水平 wx.BoxSizer
中。 比例为 0 的按钮根本不会改变。 比例为 2 的按钮在水平方向上的变化是比例为 1 的按钮的两倍。
使用 flag 参数,您可以进一步配置 wx.BoxSizer
内小部件的行为。 我们可以控制小部件之间的边框。 我们在像素中的小部件之间添加一些空间。 为了应用边框,我们需要定义将使用边框的边。 我们可以使用 |
运算符将它们组合起来; 例如 wx.LEFT | wx.BOTTOM
。 我们可以在这些标志之间进行选择
- wx.LEFT
- wx.RIGHT
- wx.BOTTOM
- wx.TOP
- wx.ALL
sizer 使用 setSizer()
方法设置到面板小部件。
#!/usr/bin/env python """ ZetCode wxPython tutorial In this example we place a panel inside another panel. author: Jan Bodnar website: www.zetcode.com last modified: July 2020 """ import wx class Example(wx.Frame): def __init__(self, parent, title): super(Example, self).__init__(parent, title=title) self.InitUI() self.Centre() def InitUI(self): panel = wx.Panel(self) panel.SetBackgroundColour('#4f5049') vbox = wx.BoxSizer(wx.VERTICAL) midPan = wx.Panel(panel) midPan.SetBackgroundColour('#ededed') vbox.Add(midPan, wx.ID_ANY, wx.EXPAND | wx.ALL, 20) panel.SetSizer(vbox) def main(): app = wx.App() ex = Example(None, title='Border') ex.Show() app.MainLoop() if __name__ == '__main__': main()
在上面的例子中,我们在一个面板周围放置了一些空间。
vbox.Add(midPan, wx.ID_ANY, wx.EXPAND | wx.ALL, 20)
在 border.py
中,我们在 midPan
面板周围放置了一个 20 像素的边框。 wx.ALL
将边框大小应用于所有四边。
如果我们使用 wx.EXPAND
标志,我们的小部件将使用分配给它的所有空间。 最后,我们还可以定义小部件的对齐方式。 我们使用以下标志来执行此操作
- wx.ALIGN_LEFT
- wx.ALIGN_RIGHT
- wx.ALIGN_TOP
- wx.ALIGN_BOTTOM
- wx.ALIGN_CENTER_VERTICAL
- wx.ALIGN_CENTER_HORIZONTAL
- wx.ALIGN_CENTER

GoToClass 示例
在下面的例子中,我们介绍了几个重要的想法。
#!/usr/bin/env python """ ZetCode wxPython tutorial In this example we create a Go To class layout with wx.BoxSizer. author: Jan Bodnar website: www.zetcode.com last modified: July 2020 """ import wx class Example(wx.Frame): def __init__(self, parent, title): super(Example, self).__init__(parent, title=title) self.InitUI() self.Centre() def InitUI(self): panel = wx.Panel(self) font = wx.SystemSettings.GetFont(wx.SYS_SYSTEM_FONT) font.SetPointSize(9) vbox = wx.BoxSizer(wx.VERTICAL) hbox1 = wx.BoxSizer(wx.HORIZONTAL) st1 = wx.StaticText(panel, label='Class Name') st1.SetFont(font) hbox1.Add(st1, flag=wx.RIGHT, border=8) tc = wx.TextCtrl(panel) hbox1.Add(tc, proportion=1) vbox.Add(hbox1, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, border=10) vbox.Add((-1, 10)) hbox2 = wx.BoxSizer(wx.HORIZONTAL) st2 = wx.StaticText(panel, label='Matching Classes') st2.SetFont(font) hbox2.Add(st2) vbox.Add(hbox2, flag=wx.LEFT | wx.TOP, border=10) vbox.Add((-1, 10)) hbox3 = wx.BoxSizer(wx.HORIZONTAL) tc2 = wx.TextCtrl(panel, style=wx.TE_MULTILINE) hbox3.Add(tc2, proportion=1, flag=wx.EXPAND) vbox.Add(hbox3, proportion=1, flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=10) vbox.Add((-1, 25)) hbox4 = wx.BoxSizer(wx.HORIZONTAL) cb1 = wx.CheckBox(panel, label='Case Sensitive') cb1.SetFont(font) hbox4.Add(cb1) cb2 = wx.CheckBox(panel, label='Nested Classes') cb2.SetFont(font) hbox4.Add(cb2, flag=wx.LEFT, border=10) cb3 = wx.CheckBox(panel, label='Non-Project classes') cb3.SetFont(font) hbox4.Add(cb3, flag=wx.LEFT, border=10) vbox.Add(hbox4, flag=wx.LEFT, border=10) vbox.Add((-1, 25)) hbox5 = wx.BoxSizer(wx.HORIZONTAL) btn1 = wx.Button(panel, label='Ok', size=(70, 30)) hbox5.Add(btn1) btn2 = wx.Button(panel, label='Close', size=(70, 30)) hbox5.Add(btn2, flag=wx.LEFT|wx.BOTTOM, border=5) vbox.Add(hbox5, flag=wx.ALIGN_RIGHT|wx.RIGHT, border=10) panel.SetSizer(vbox) def main(): app = wx.App() ex = Example(None, title='Go To Class') ex.Show() app.MainLoop() if __name__ == '__main__': main()
布局很简单。 我们创建一个垂直的 sizer。 然后我们向其中放入五个水平 sizer。
font = wx.SystemSettings.GetFont(wx.SYS_SYSTEM_FONT) font.SetPointSize(9)
我们将字体大小更改为 9 像素。
vbox.Add(hbox3, proportion=1, flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=10) vbox.Add((-1, 25))
我们已经知道,我们可以通过将 flag 参数与边框参数组合来控制小部件之间的距离。 但有一个真正的约束。 在 Add()
方法中,我们只能为所有给定的边指定一个边框。 在我们的示例中,我们向右和向左提供 10 像素。 但我们不能在底部提供 25 像素。 我们可以做的是在底部提供 10 像素,或者省略 wx.BOTTOM
时提供 0 像素。 因此,如果我们需要不同的值,我们可以添加一些额外的空间。 使用 Add()
方法,我们也可以插入小部件和空间。
vbox.Add(hbox5, flag=wx.ALIGN_RIGHT|wx.RIGHT, border=10)
我们将两个按钮放在窗口的右侧。 要实现这一点,有三件事很重要:比例、对齐标志和 wx.EXPAND
标志。 比例必须为零。 当我们调整窗口大小时,按钮不应更改其大小。 我们不得指定 wx.EXPAND
标志。 按钮只占用分配给它们的区域。 最后,我们必须指定 wx.ALIGN_RIGHT
标志。 水平 sizer 从窗口的左侧向右侧延伸。 因此,如果我们指定 wx.ALIGN_RIGHT
标志,按钮将放置在右侧。

wx.GridSizer
wx.GridSizer
在二维表格中布局小部件。 表中的每个单元格都具有相同的大小。
wx.GridSizer(int rows=1, int cols=0, int vgap=0, int hgap=0)
在构造函数中,我们指定表中行和列的数量以及单元格之间的垂直和水平空间。
在我们的示例中,我们创建一个计算器的框架。
#!/usr/bin/env python """ ZetCode wxPython tutorial In this example we create a layout of a calculator with wx.GridSizer. author: Jan Bodnar website: www.zetcode.com last modified: July 2020 """ import wx class Example(wx.Frame): def __init__(self, parent, title): super(Example, self).__init__(parent, title=title) self.InitUI() self.Centre() def InitUI(self): menubar = wx.MenuBar() fileMenu = wx.Menu() menubar.Append(fileMenu, '&File') self.SetMenuBar(menubar) vbox = wx.BoxSizer(wx.VERTICAL) self.display = wx.TextCtrl(self, style=wx.TE_RIGHT) vbox.Add(self.display, flag=wx.EXPAND|wx.TOP|wx.BOTTOM, border=4) gs = wx.GridSizer(5, 4, 5, 5) gs.AddMany( [(wx.Button(self, label='Cls'), 0, wx.EXPAND), (wx.Button(self, label='Bck'), 0, wx.EXPAND), (wx.StaticText(self), wx.EXPAND), (wx.Button(self, label='Close'), 0, wx.EXPAND), (wx.Button(self, label='7'), 0, wx.EXPAND), (wx.Button(self, label='8'), 0, wx.EXPAND), (wx.Button(self, label='9'), 0, wx.EXPAND), (wx.Button(self, label='/'), 0, wx.EXPAND), (wx.Button(self, label='4'), 0, wx.EXPAND), (wx.Button(self, label='5'), 0, wx.EXPAND), (wx.Button(self, label='6'), 0, wx.EXPAND), (wx.Button(self, label='*'), 0, wx.EXPAND), (wx.Button(self, label='1'), 0, wx.EXPAND), (wx.Button(self, label='2'), 0, wx.EXPAND), (wx.Button(self, label='3'), 0, wx.EXPAND), (wx.Button(self, label='-'), 0, wx.EXPAND), (wx.Button(self, label='0'), 0, wx.EXPAND), (wx.Button(self, label='.'), 0, wx.EXPAND), (wx.Button(self, label='='), 0, wx.EXPAND), (wx.Button(self, label='+'), 0, wx.EXPAND) ]) vbox.Add(gs, proportion=1, flag=wx.EXPAND) self.SetSizer(vbox) def main(): app = wx.App() ex = Example(None, title='Calculator') ex.Show() app.MainLoop() if __name__ == '__main__': main()
请注意我们如何设法在 Bck 和 Close 按钮之间留出一个空格。 我们只是在那里放置了一个空的 wx.StaticText
。
在我们的示例中,我们使用了 AddMany()
方法。 这是一个用于一次添加多个小部件的便捷方法。
gs.AddMany( [(wx.Button(self, label='Cls'), 0, wx.EXPAND), ...
小部件按添加的顺序放置在表中。 首先填充第一行,然后填充第二行,依此类推。

wx.FlexGridSizer
此 sizer 类似于 wx.GridSizer
。 它也将其小部件布局在一个二维表格中。 它为其添加了一些灵活性。 wx.GridSizer
单元格的大小相同。 wx.FlexGridSizer
中的所有单元格在同一行中具有相同的高度。 所有单元格在同一列中具有相同的宽度。 但是所有行和列不一定具有相同的高度或宽度。
wx.FlexGridSizer(int rows=1, int cols=0, int vgap=0, int hgap=0)
rows
和 cols
指定 sizer 中行和列的数量。 vgap
和 hgap
在两个方向上都添加了小部件之间的一些空间。
很多时候,开发人员必须开发用于数据输入和修改的对话框。 我发现 wx.FlexGridSizer
适合此类任务。 开发人员可以使用此 sizer 轻松设置一个对话框窗口。 这也可以使用 wx.GridSizer
完成,但由于每个单元格必须具有相同大小的约束,它看起来不会很好。
#!/usr/bin/env python """ ZetCode wxPython tutorial In this example we create review layout with wx.FlexGridSizer. author: Jan Bodnar website: www.zetcode.com last modified: July 2020 """ import wx class Example(wx.Frame): def __init__(self, parent, title): super(Example, self).__init__(parent, title=title) self.InitUI() self.Centre() self.Show() def InitUI(self): panel = wx.Panel(self) hbox = wx.BoxSizer(wx.HORIZONTAL) fgs = wx.FlexGridSizer(3, 2, 9, 25) title = wx.StaticText(panel, label="Title") author = wx.StaticText(panel, label="Author") review = wx.StaticText(panel, label="Review") tc1 = wx.TextCtrl(panel) tc2 = wx.TextCtrl(panel) tc3 = wx.TextCtrl(panel, style=wx.TE_MULTILINE) fgs.AddMany([(title), (tc1, 1, wx.EXPAND), (author), (tc2, 1, wx.EXPAND), (review, 1, wx.EXPAND), (tc3, 1, wx.EXPAND)]) fgs.AddGrowableRow(2, 1) fgs.AddGrowableCol(1, 1) hbox.Add(fgs, proportion=1, flag=wx.ALL|wx.EXPAND, border=15) panel.SetSizer(hbox) def main(): app = wx.App() ex = Example(None, title='Review') ex.Show() app.MainLoop() if __name__ == '__main__': main()
在上面的代码示例中,我们创建了一个带有 FlexGridSizer
的 Review 窗口。
hbox = wx.BoxSizer(wx.HORIZONTAL) ... hbox.Add(fgs, proportion=1, flag=wx.ALL|wx.EXPAND, border=15)
我们创建一个水平框 sizer,以便在小部件表周围放置一些空间(15 像素)。
fgs.AddMany([(title), (tc1, 1, wx.EXPAND), (author), (tc2, 1, wx.EXPAND), (review, 1, wx.EXPAND), (tc3, 1, wx.EXPAND)])
我们使用 AddMany()
方法将小部件添加到 sizer。 wx.FlexGridSizer
和 wx.GridSizer
共享此方法。
fgs.AddGrowableRow(2, 1) fgs.AddGrowableCol(1, 1)
我们使第三行和第二列可增长。 通过这种方式,我们让文本控件在调整窗口大小时增长。 前两个文本控件将在水平方向增长,第三个文本控件将在两个方向增长。 我们不得忘记使用 wx.EXPAND
使小部件可扩展才能使其工作。

wx.GridBagSizer
wx.GridBagSizer
是 wxPython 中最灵活的 sizer。 使用。 这种 sizer 并不典型,仅适用于 wxPython。 我们也可以在其他工具包中找到它。
此 sizer 允许显式定位项目。 项目也可以选择跨越多个行或列。 wx.GridBagSizer
有一个简单的构造函数。
wx.GridBagSizer(integer vgap, integer hgap)
垂直和水平间隙定义了所有子级之间使用的像素空间。 我们使用 Add()
方法将项目添加到网格中。
Add(self, item, tuple pos, tuple span=wx.DefaultSpan, integer flag=0, integer border=0, userData=None)
Item 是您插入网格中的一个小部件。 pos 指定在虚拟网格中的位置。 左上角的单元格的 pos 为 (0, 0)。 span 是一个小部件的可选跨度; 例如。 (3, 2) 的跨度跨越一个跨越 3 行和 2 列的小部件。 标志和边框之前通过 wx.BoxSizer
进行了讨论。 当调整窗口大小时,网格中的项目可以更改它们的大小或保持默认大小。 如果我们希望您的项目增长和收缩,我们可以使用以下两种方法
AddGrowableRow(integer row) AddGrowableCol(integer col)
重命名窗口示例
在我们的第一个示例中,我们创建一个重命名窗口。 它将有一个 wx.StaticText
、一个 wx.TextCtrl
和两个 wx.Button
小部件。
#!/usr/bin/env python """ ZetCode wxPython tutorial In this example we create a rename layout with wx.GridBagSizer. author: Jan Bodnar website: www.zetcode.com last modified: July 2020 """ import wx class Example(wx.Frame): def __init__(self, parent, title): super(Example, self).__init__(parent, title=title) self.InitUI() self.Centre() def InitUI(self): panel = wx.Panel(self) sizer = wx.GridBagSizer(4, 4) text = wx.StaticText(panel, label="Rename To") sizer.Add(text, pos=(0, 0), flag=wx.TOP|wx.LEFT|wx.BOTTOM, border=5) tc = wx.TextCtrl(panel) sizer.Add(tc, pos=(1, 0), span=(1, 5), flag=wx.EXPAND|wx.LEFT|wx.RIGHT, border=5) buttonOk = wx.Button(panel, label="Ok", size=(90, 28)) buttonClose = wx.Button(panel, label="Close", size=(90, 28)) sizer.Add(buttonOk, pos=(3, 3)) sizer.Add(buttonClose, pos=(3, 4), flag=wx.RIGHT|wx.BOTTOM, border=10) sizer.AddGrowableCol(1) sizer.AddGrowableRow(2) panel.SetSizer(sizer) def main(): app = wx.App() ex = Example(None, title='Rename') ex.Show() app.MainLoop() if __name__ == '__main__': main()
我们必须将窗口看作一个大的网格表。
text = wx.StaticText(panel, label="Rename To") sizer.Add(text, pos=(0, 0), flag=wx.TOP|wx.LEFT|wx.BOTTOM, border=10)
文本“重命名为”转到左上角。 因此我们指定 (0, 0) 位置。 并且我们在底部、左侧和底部添加一些空间。
tc = wx.TextCtrl(panel) sizer.Add(tc, pos=(1, 0), span=(1, 5), flag=wx.EXPAND|wx.LEFT|wx.RIGHT, border=5)
wx.TextCtrl
转到第二行的开头 (1, 0)。 记住,我们从零开始计数。 它扩展 1 行和 5 列 (1, 5)。 我们在小部件的左侧和右侧放置 5 像素的空间。
sizer.Add(buttonOk, pos=(3, 3)) sizer.Add(buttonClose, pos=(3, 4), flag=wx.RIGHT|wx.BOTTOM, border=10)
我们将两个按钮放在第四行。 第三行留空,这样我们在 wx.TextCtrl
和按钮之间留出一些空间。 我们将确定按钮放在第四列中,将关闭按钮放在第五列中。 请注意,一旦我们将一些空间应用于一个小部件,它就会应用于整行。 这就是我们没有为确定按钮指定底部空间的原因。 一位细心的读者可能会注意到,我们没有在两个按钮之间指定任何空间; 也就是说,我们没有在确定按钮的右侧或关闭按钮的右侧放置任何空间。 在 wx.GridBagSizer
的构造函数中,我们在所有小部件之间放置了一些空间。 所以已经有一些空间了。
sizer.AddGrowableCol(1) sizer.AddGrowableRow(2)
我们必须做的最后一件事是使我们的对话框可调整大小。 我们使第二列和第三行可增长。 现在我们可以展开或收缩我们的窗口。 尝试注释这两行,看看会发生什么。

新类示例
在下一个示例中,我们创建了一个可以在 JDeveloper 中找到的窗口。 这是一个用于在 Java 中创建新类的窗口。
#!/usr/bin/env python """ ZetCode wxPython tutorial In this example we create a new class layout with wx.GridBagSizer. author: Jan Bodnar website: www.zetcode.com last modified: July 2020 """ import wx class Example(wx.Frame): def __init__(self, parent, title): super(Example, self).__init__(parent, title=title) self.InitUI() self.Centre() def InitUI(self): panel = wx.Panel(self) sizer = wx.GridBagSizer(5, 5) text1 = wx.StaticText(panel, label="Java Class") sizer.Add(text1, pos=(0, 0), flag=wx.TOP|wx.LEFT|wx.BOTTOM, border=15) icon = wx.StaticBitmap(panel, bitmap=wx.Bitmap('exec.png')) sizer.Add(icon, pos=(0, 4), flag=wx.TOP|wx.RIGHT|wx.ALIGN_RIGHT, border=5) line = wx.StaticLine(panel) sizer.Add(line, pos=(1, 0), span=(1, 5), flag=wx.EXPAND|wx.BOTTOM, border=10) text2 = wx.StaticText(panel, label="Name") sizer.Add(text2, pos=(2, 0), flag=wx.LEFT, border=10) tc1 = wx.TextCtrl(panel) sizer.Add(tc1, pos=(2, 1), span=(1, 3), flag=wx.TOP|wx.EXPAND) text3 = wx.StaticText(panel, label="Package") sizer.Add(text3, pos=(3, 0), flag=wx.LEFT|wx.TOP, border=10) tc2 = wx.TextCtrl(panel) sizer.Add(tc2, pos=(3, 1), span=(1, 3), flag=wx.TOP|wx.EXPAND, border=5) button1 = wx.Button(panel, label="Browse...") sizer.Add(button1, pos=(3, 4), flag=wx.TOP|wx.RIGHT, border=5) text4 = wx.StaticText(panel, label="Extends") sizer.Add(text4, pos=(4, 0), flag=wx.TOP|wx.LEFT, border=10) combo = wx.ComboBox(panel) sizer.Add(combo, pos=(4, 1), span=(1, 3), flag=wx.TOP|wx.EXPAND, border=5) button2 = wx.Button(panel, label="Browse...") sizer.Add(button2, pos=(4, 4), flag=wx.TOP|wx.RIGHT, border=5) sb = wx.StaticBox(panel, label="Optional Attributes") boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL) boxsizer.Add(wx.CheckBox(panel, label="Public"), flag=wx.LEFT|wx.TOP, border=5) boxsizer.Add(wx.CheckBox(panel, label="Generate Default Constructor"), flag=wx.LEFT, border=5) boxsizer.Add(wx.CheckBox(panel, label="Generate Main Method"), flag=wx.LEFT|wx.BOTTOM, border=5) sizer.Add(boxsizer, pos=(5, 0), span=(1, 5), flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT , border=10) button3 = wx.Button(panel, label='Help') sizer.Add(button3, pos=(7, 0), flag=wx.LEFT, border=10) button4 = wx.Button(panel, label="Ok") sizer.Add(button4, pos=(7, 3)) button5 = wx.Button(panel, label="Cancel") sizer.Add(button5, pos=(7, 4), span=(1, 1), flag=wx.BOTTOM|wx.RIGHT, border=10) sizer.AddGrowableCol(2) panel.SetSizer(sizer) sizer.Fit(self) def main(): app = wx.App() ex = Example(None, title="Create Java Class") ex.Show() app.MainLoop() if __name__ == '__main__': main()
这是一个更复杂的布局。 我们同时使用 wx.GridBagSizer
和 wx.StaticBoxsizer
。
line = wx.StaticLine(panel) sizer.Add(line, pos=(1, 0), span=(1, 5), flag=wx.EXPAND|wx.BOTTOM, border=10)
这是用于分隔布局中小部件组的行。
icon = wx.StaticBitmap(panel, bitmap=wx.Bitmap('exec.png')) sizer.Add(icon, pos=(0, 4), flag=wx.TOP|wx.RIGHT|wx.ALIGN_RIGHT, border=5)
我们将 wx.StaticBitmap
放入网格的第一行。 我们将其放在行的右侧。
sb = wx.StaticBox(panel, label="Optional Attributes") boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)
wxStaticBoxSizer
就像一个普通的 wx.BoxSizer
,但它在 sizer 周围添加了一个静态框。 我们将复选框放入静态框 sizer 中。

wxPython 教程的这一部分专门用于布局管理。