原文: http://zetcode.com/wxpython/layout/

典型的应用由各种小部件组成。 这些小部件放置在容器小部件内。 程序员必须管理应用的布局。 这不是一件容易的事。 在 wxPython 中,可以使用绝对定位或使用大小调整器来布局小部件。

绝对定位

程序员以像素为单位指定每个小部件的位置和大小。 绝对定位有几个缺点:

  • 如果我们调整窗口大小,则小部件的大小和位置不会改变。
  • 在各种平台上,应用看起来都不同。
  • 在应用中更改字体可能会破坏布局。
  • 如果决定更改布局,则必须完全重做布局,这既繁琐又耗时。

在某些情况下,我们可能会使用绝对定位。 例如,小的测试示例。 但是大多数情况下,在现实世界的程序中,程序员使用大小调整器。

在我们的示例中,我们有一个简单的文本编辑器框架。 如果我们调整窗口大小,则wx.TextCtrl的大小不会像我们期望的那样改变。

absolute.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this example, we lay out widgets using
  6. absolute positioning.
  7. author: Jan Bodnar
  8. website: www.zetcode.com
  9. last modified: April 2018
  10. """
  11. import wx
  12. class Example(wx.Frame):
  13. def __init__(self, parent, title):
  14. super(Example, self).__init__(parent, title=title,
  15. size=(350, 300))
  16. self.InitUI()
  17. self.Centre()
  18. def InitUI(self):
  19. self.panel = wx.Panel(self)
  20. self.panel.SetBackgroundColour("gray")
  21. self.LoadImages()
  22. self.mincol.SetPosition((20, 20))
  23. self.bardejov.SetPosition((40, 160))
  24. self.rotunda.SetPosition((170, 50))
  25. def LoadImages(self):
  26. self.mincol = wx.StaticBitmap(self.panel, wx.ID_ANY,
  27. wx.Bitmap("mincol.jpg", wx.BITMAP_TYPE_ANY))
  28. self.bardejov = wx.StaticBitmap(self.panel, wx.ID_ANY,
  29. wx.Bitmap("bardejov.jpg", wx.BITMAP_TYPE_ANY))
  30. self.rotunda = wx.StaticBitmap(self.panel, wx.ID_ANY,
  31. wx.Bitmap("rotunda.jpg", wx.BITMAP_TYPE_ANY))
  32. def main():
  33. app = wx.App()
  34. ex = Example(None, title='Absolute positioning')
  35. ex.Show()
  36. app.MainLoop()
  37. if __name__ == '__main__':
  38. main()

在上面的示例中,我们使用绝对坐标定位了三个图像。

  1. self.mincol.SetPosition((20, 20))

使用SetPosition()方法,我们将图像放置在x = 20y = 20坐标处。

wxPython 中的布局管理 - 图1

图:绝对定位

使用大小调整器

大小调整器确实解决了绝对定位中提到的所有这些问题。 wxPython 具有以下大小调整器:

  • wx.BoxSizer
  • wx.StaticBoxSizer
  • wx.GridSizer
  • wx.FlexGridSizer
  • wx.GridBagSizer

wx.BoxSizer

wx.BoxSizer使我们可以将几个小部件放在一行或一列中。 我们可以将另一个调整器放到现有的调整器中。 这样,我们可以创建非常复杂的布局。

  1. box = wx.BoxSizer(integer orient)
  2. box.Add(wx.Window window, integer proportion=0, integer flag = 0, integer border = 0)

方向可以是wx.VERTICALwx.HORIZONTAL。 通过Add()方法将小部件添加到wx.BoxSizer中。 为了理解它,我们需要查看它的参数。

比例参数定义小部件在定义的方向上如何变化的比例。 假设我们有三个比例分别为 0、1 和 2 的按钮。它们被添加到水平wx.BoxSizer中。 比例为 0 的按钮完全不会改变。 在水平方向上比例为 2 的按钮的变化比比例为 1 的按钮大两倍。

使用flag参数,您可以进一步在wx.BoxSizer中配置小部件的行为。 我们可以控制小部件之间的边界。 我们在小部件之间添加一些像素间距。 为了应用边框,我们需要定义要使用边框的边。 我们可以将它们与|运算符结合使用; 例如wx.LEFT | wx.BOTTOM。 我们可以在这些标志之间进行选择:

  • wx.LEFT
  • wx.RIGHT
  • wx.TOP
  • wx.BOTTOM
  • wx.ALL

通过setSizer()方法将大小调整器设置为面板小部件。

border.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this example we place a panel inside
  6. another panel.
  7. author: Jan Bodnar
  8. website: www.zetcode.com
  9. last modified: April 2018
  10. """
  11. import wx
  12. class Example(wx.Frame):
  13. def __init__(self, parent, title):
  14. super(Example, self).__init__(parent, title=title)
  15. self.InitUI()
  16. self.Centre()
  17. def InitUI(self):
  18. panel = wx.Panel(self)
  19. panel.SetBackgroundColour('#4f5049')
  20. vbox = wx.BoxSizer(wx.VERTICAL)
  21. midPan = wx.Panel(panel)
  22. midPan.SetBackgroundColour('#ededed')
  23. vbox.Add(midPan, wx.ID_ANY, wx.EXPAND | wx.ALL, 20)
  24. panel.SetSizer(vbox)
  25. def main():
  26. app = wx.App()
  27. ex = Example(None, title='Border')
  28. ex.Show()
  29. app.MainLoop()
  30. if __name__ == '__main__':
  31. main()

在上面的示例中,我们在面板周围放置了一些空间。

  1. 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

wxPython 中的布局管理 - 图2

图:面板周围的边框

GoToClass示例

在下面的示例中,我们介绍了几个重要的想法。

goto_class.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this example we create a Go To class
  6. layout with wx.BoxSizer.
  7. author: Jan Bodnar
  8. website: www.zetcode.com
  9. last modified: April 2018
  10. """
  11. import wx
  12. class Example(wx.Frame):
  13. def __init__(self, parent, title):
  14. super(Example, self).__init__(parent, title=title)
  15. self.InitUI()
  16. self.Centre()
  17. def InitUI(self):
  18. panel = wx.Panel(self)
  19. font = wx.SystemSettings.GetFont(wx.SYS_SYSTEM_FONT)
  20. font.SetPointSize(9)
  21. vbox = wx.BoxSizer(wx.VERTICAL)
  22. hbox1 = wx.BoxSizer(wx.HORIZONTAL)
  23. st1 = wx.StaticText(panel, label='Class Name')
  24. st1.SetFont(font)
  25. hbox1.Add(st1, flag=wx.RIGHT, border=8)
  26. tc = wx.TextCtrl(panel)
  27. hbox1.Add(tc, proportion=1)
  28. vbox.Add(hbox1, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, border=10)
  29. vbox.Add((-1, 10))
  30. hbox2 = wx.BoxSizer(wx.HORIZONTAL)
  31. st2 = wx.StaticText(panel, label='Matching Classes')
  32. st2.SetFont(font)
  33. hbox2.Add(st2)
  34. vbox.Add(hbox2, flag=wx.LEFT | wx.TOP, border=10)
  35. vbox.Add((-1, 10))
  36. hbox3 = wx.BoxSizer(wx.HORIZONTAL)
  37. tc2 = wx.TextCtrl(panel, style=wx.TE_MULTILINE)
  38. hbox3.Add(tc2, proportion=1, flag=wx.EXPAND)
  39. vbox.Add(hbox3, proportion=1, flag=wx.LEFT|wx.RIGHT|wx.EXPAND,
  40. border=10)
  41. vbox.Add((-1, 25))
  42. hbox4 = wx.BoxSizer(wx.HORIZONTAL)
  43. cb1 = wx.CheckBox(panel, label='Case Sensitive')
  44. cb1.SetFont(font)
  45. hbox4.Add(cb1)
  46. cb2 = wx.CheckBox(panel, label='Nested Classes')
  47. cb2.SetFont(font)
  48. hbox4.Add(cb2, flag=wx.LEFT, border=10)
  49. cb3 = wx.CheckBox(panel, label='Non-Project classes')
  50. cb3.SetFont(font)
  51. hbox4.Add(cb3, flag=wx.LEFT, border=10)
  52. vbox.Add(hbox4, flag=wx.LEFT, border=10)
  53. vbox.Add((-1, 25))
  54. hbox5 = wx.BoxSizer(wx.HORIZONTAL)
  55. btn1 = wx.Button(panel, label='Ok', size=(70, 30))
  56. hbox5.Add(btn1)
  57. btn2 = wx.Button(panel, label='Close', size=(70, 30))
  58. hbox5.Add(btn2, flag=wx.LEFT|wx.BOTTOM, border=5)
  59. vbox.Add(hbox5, flag=wx.ALIGN_RIGHT|wx.RIGHT, border=10)
  60. panel.SetSizer(vbox)
  61. def main():
  62. app = wx.App()
  63. ex = Example(None, title='Go To Class')
  64. ex.Show()
  65. app.MainLoop()
  66. if __name__ == '__main__':
  67. main()

布局僵硬。 我们创建一个垂直大小调整器。 然后,我们将五个水平大小调整器放入其中。

  1. font = wx.SystemSettings.GetFont(wx.SYS_SYSTEM_FONT)
  2. font.SetPointSize(9)

我们将字体大小更改为 9 像素。

  1. vbox.Add(hbox3, proportion=1, flag=wx.LEFT|wx.RIGHT|wx.EXPAND,
  2. border=10)
  3. vbox.Add((-1, 25))

我们已经知道可以通过组合flag参数和border参数来控制小部件之间的距离。 但是有一个真正的约束。 在Add()方法中,我们只能为所有给定的边指定一个边框。 在我们的示例中,我们在右侧和左侧分别设置了 10 像素。 但是我们不能给底部 25 像素。 我们可以做的是在底部给 10px,如果省略wx.BOTTOM则给 0px。 因此,如果我们需要不同的值,则可以添加一些额外的空间。 使用Add()方法,我们也可以插入小部件和空间。

  1. vbox.Add(hbox5, flag=wx.ALIGN_RIGHT|wx.RIGHT, border=10)

我们将两个按钮放在窗口的右侧。 实现这一点很重要的三件事:比例,对齐标志和wx.EXPAND标志。 比例必须为零。 调整窗口大小时,按钮的大小不应更改。 我们一定不要指定wx.EXPAND标志。 这些按钮仅占用分配给它们的区域。 最后,我们必须指定wx.ALIGN_RIGHT标志。 水平大小调整器从窗口的左侧扩展到右侧。 因此,如果我们指定wx.ALIGN_RIGHT标志,则按钮将放置在右侧。

wxPython 中的布局管理 - 图3

图:GoToClass窗口

wx.GridSizer

wx.GridSizer在二维表中布置小部件。 表格中的每个单元格都具有相同的大小。

  1. wx.GridSizer(int rows=1, int cols=0, int vgap=0, int hgap=0)

在构造器中,我们指定表中的行和列数以及单元格之间的垂直和水平空间。

在我们的示例中,我们创建了计算器的骨架。

calculator.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this example we create a layout
  6. of a calculator with wx.GridSizer.
  7. author: Jan Bodnar
  8. website: www.zetcode.com
  9. last modified: April 2018
  10. """
  11. import wx
  12. class Example(wx.Frame):
  13. def __init__(self, parent, title):
  14. super(Example, self).__init__(parent, title=title)
  15. self.InitUI()
  16. self.Centre()
  17. def InitUI(self):
  18. menubar = wx.MenuBar()
  19. fileMenu = wx.Menu()
  20. menubar.Append(fileMenu, '&File')
  21. self.SetMenuBar(menubar)
  22. vbox = wx.BoxSizer(wx.VERTICAL)
  23. self.display = wx.TextCtrl(self, style=wx.TE_RIGHT)
  24. vbox.Add(self.display, flag=wx.EXPAND|wx.TOP|wx.BOTTOM, border=4)
  25. gs = wx.GridSizer(5, 4, 5, 5)
  26. gs.AddMany( [(wx.Button(self, label='Cls'), 0, wx.EXPAND),
  27. (wx.Button(self, label='Bck'), 0, wx.EXPAND),
  28. (wx.StaticText(self), wx.EXPAND),
  29. (wx.Button(self, label='Close'), 0, wx.EXPAND),
  30. (wx.Button(self, label='7'), 0, wx.EXPAND),
  31. (wx.Button(self, label='8'), 0, wx.EXPAND),
  32. (wx.Button(self, label='9'), 0, wx.EXPAND),
  33. (wx.Button(self, label='/'), 0, wx.EXPAND),
  34. (wx.Button(self, label='4'), 0, wx.EXPAND),
  35. (wx.Button(self, label='5'), 0, wx.EXPAND),
  36. (wx.Button(self, label='6'), 0, wx.EXPAND),
  37. (wx.Button(self, label='*'), 0, wx.EXPAND),
  38. (wx.Button(self, label='1'), 0, wx.EXPAND),
  39. (wx.Button(self, label='2'), 0, wx.EXPAND),
  40. (wx.Button(self, label='3'), 0, wx.EXPAND),
  41. (wx.Button(self, label='-'), 0, wx.EXPAND),
  42. (wx.Button(self, label='0'), 0, wx.EXPAND),
  43. (wx.Button(self, label='.'), 0, wx.EXPAND),
  44. (wx.Button(self, label='='), 0, wx.EXPAND),
  45. (wx.Button(self, label='+'), 0, wx.EXPAND) ])
  46. vbox.Add(gs, proportion=1, flag=wx.EXPAND)
  47. self.SetSizer(vbox)
  48. def main():
  49. app = wx.App()
  50. ex = Example(None, title='Calculator')
  51. ex.Show()
  52. app.MainLoop()
  53. if __name__ == '__main__':
  54. main()

注意我们如何设法在返回和关闭按钮之间放置一个空格。 我们只需在其中放置一个空的wx.StaticText

在我们的示例中,我们使用了AddMany()方法。 这是一次同时添加多个小部件的便捷方法。

  1. gs.AddMany( [(wx.Button(self, label='Cls'), 0, wx.EXPAND),
  2. ...

将小部件按顺序放置在表中,然后将它们添加。 第一行先填充,然后第二行等。

wxPython 中的布局管理 - 图4

图:计算器

wx.FlexGridSizer

该大小调整器类似于wx.GridSizer。 它还确实将其小部件布置在二维表中。 它增加了一些灵活性。 wx.GridSizer细胞大小相同。 wx.FlexGridSizer中的所有单元格都具有相同的高度。 一列中所有单元格的宽度均相同。 但是,所有行和列不一定都具有相同的高度或宽度。

  1. wx.FlexGridSizer(int rows=1, int cols=0, int vgap=0, int hgap=0)

rowscols指定大小调整器中的行数和列数。 vgaphgap在两个方向的小部件之间添加了一些空间。

很多时候,开发者必须开发用于数据输入和修改的对话框。 我发现wx.FlexGridSizer适用于此类任务。 开发者可以使用此 sizer 轻松设置对话框窗口。 也可以使用wx.GridSizer完成此操作,但由于每个单元格必须具有相同的大小的限制,因此看起来不太好。

review.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this example we create review
  6. layout with wx.FlexGridSizer.
  7. author: Jan Bodnar
  8. website: www.zetcode.com
  9. last modified: April 2018
  10. """
  11. import wx
  12. class Example(wx.Frame):
  13. def __init__(self, parent, title):
  14. super(Example, self).__init__(parent, title=title)
  15. self.InitUI()
  16. self.Centre()
  17. self.Show()
  18. def InitUI(self):
  19. panel = wx.Panel(self)
  20. hbox = wx.BoxSizer(wx.HORIZONTAL)
  21. fgs = wx.FlexGridSizer(3, 2, 9, 25)
  22. title = wx.StaticText(panel, label="Title")
  23. author = wx.StaticText(panel, label="Author")
  24. review = wx.StaticText(panel, label="Review")
  25. tc1 = wx.TextCtrl(panel)
  26. tc2 = wx.TextCtrl(panel)
  27. tc3 = wx.TextCtrl(panel, style=wx.TE_MULTILINE)
  28. fgs.AddMany([(title), (tc1, 1, wx.EXPAND), (author),
  29. (tc2, 1, wx.EXPAND), (review, 1, wx.EXPAND), (tc3, 1, wx.EXPAND)])
  30. fgs.AddGrowableRow(2, 1)
  31. fgs.AddGrowableCol(1, 1)
  32. hbox.Add(fgs, proportion=1, flag=wx.ALL|wx.EXPAND, border=15)
  33. panel.SetSizer(hbox)
  34. def main():
  35. app = wx.App()
  36. ex = Example(None, title='Review')
  37. ex.Show()
  38. app.MainLoop()
  39. if __name__ == '__main__':
  40. main()

在上面的代码示例中,我们使用FlexGridSizer创建一个Review窗口。

  1. hbox = wx.BoxSizer(wx.HORIZONTAL)
  2. ...
  3. hbox.Add(fgs, proportion=1, flag=wx.ALL|wx.EXPAND, border=15)

我们创建一个水平框大小调整器,以便在小部件表周围放置一些空间(15 像素)。

  1. fgs.AddMany([(title), (tc1, 1, wx.EXPAND), (author),
  2. (tc2, 1, wx.EXPAND), (review, 1, wx.EXPAND), (tc3, 1, wx.EXPAND)])

我们使用AddMany()方法将小部件添加到大小调整器中。 wx.FlexGridSizerwx.GridSizer都共享此方法。

  1. fgs.AddGrowableRow(2, 1)
  2. fgs.AddGrowableCol(1, 1)

我们使第三行和第二列可增长。 这样,当调整窗口大小时,我们使文本控件增加。 前两个文本控件将在水平方向上增长,第三个文本控件将在两个方向上增长。 我们一定不要忘记使小部件可以使用wx.EXPAND进行扩展以使其起作用。

wxPython 中的布局管理 - 图5

图:回顾 example

wx.GridBagSizer

wx.GridBagSizer是 wxPython 中最灵活的大小调整器。 这种大小调整器不仅仅适用于 wxPython。 我们也可以在其他工具包中找到它。

该大小调整器可以显式定位项目。 项还可以选择跨越多个行或一列。 wx.GridBagSizer具有简单的构造器。

  1. wx.GridBagSizer(integer vgap, integer hgap)

垂直和水平间隙定义了所有子级之间使用的像素间隔。 我们使用Add()方法将项目添加到网格中。

  1. Add(self, item, tuple pos, tuple span=wx.DefaultSpan, integer flag=0,
  2. integer border=0, userData=None)

Item是插入网格中的小部件。 pos 指定虚拟网格中的位置。 左上角的单元格的位置为(0,0)。 范围是窗口小部件的可选范围; 例如 (3,2)的范围跨 3 行和 2 列跨越一个窗口小部件。 wx.BoxSizer前面已经讨论了标志和边界。 调整窗口大小时,网格中的项目可以更改其大小或保留默认大小。 如果我们希望您的项目增加和缩小,可以使用以下两种方法:

  1. AddGrowableRow(integer row)
  2. AddGrowableCol(integer col)

重命名窗口示例

在第一个示例中,我们创建一个“重命名”窗口。 它将具有一个wx.StaticText,一个wx.TextCtrl和两个wx.Button小部件。

rename.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this example we create a rename layout
  6. with wx.GridBagSizer.
  7. author: Jan Bodnar
  8. website: www.zetcode.com
  9. last modified: April 2018
  10. """
  11. import wx
  12. class Example(wx.Frame):
  13. def __init__(self, parent, title):
  14. super(Example, self).__init__(parent, title=title)
  15. self.InitUI()
  16. self.Centre()
  17. def InitUI(self):
  18. panel = wx.Panel(self)
  19. sizer = wx.GridBagSizer(4, 4)
  20. text = wx.StaticText(panel, label="Rename To")
  21. sizer.Add(text, pos=(0, 0), flag=wx.TOP|wx.LEFT|wx.BOTTOM, border=5)
  22. tc = wx.TextCtrl(panel)
  23. sizer.Add(tc, pos=(1, 0), span=(1, 5),
  24. flag=wx.EXPAND|wx.LEFT|wx.RIGHT, border=5)
  25. buttonOk = wx.Button(panel, label="Ok", size=(90, 28))
  26. buttonClose = wx.Button(panel, label="Close", size=(90, 28))
  27. sizer.Add(buttonOk, pos=(3, 3))
  28. sizer.Add(buttonClose, pos=(3, 4), flag=wx.RIGHT|wx.BOTTOM, border=10)
  29. sizer.AddGrowableCol(1)
  30. sizer.AddGrowableRow(2)
  31. panel.SetSizer(sizer)
  32. def main():
  33. app = wx.App()
  34. ex = Example(None, title='Rename')
  35. ex.Show()
  36. app.MainLoop()
  37. if __name__ == '__main__':
  38. main()

我们必须将窗口视为一个大的网格表。

  1. text = wx.StaticText(panel, label="Rename To")
  2. sizer.Add(text, pos=(0, 0), flag=wx.TOP|wx.LEFT|wx.BOTTOM, border=10)

文本“重命名为”转到左上角。 因此,我们指定(0,0)位置。 然后在底部,左侧和底部添加一些空间。

  1. tc = wx.TextCtrl(panel)
  2. sizer.Add(tc, pos=(1, 0), span=(1, 5),
  3. flag=wx.EXPAND|wx.LEFT|wx.RIGHT, border=5)

wx.TextCtrl转到第二行的开头(1、0)。 请记住,我们从零开始计数。 它扩展了 1 行和 5 列(1、5)。 然后,在小部件的左侧和右侧放置 5 个像素的空间。

  1. sizer.Add(buttonOk, pos=(3, 3))
  2. sizer.Add(buttonClose, pos=(3, 4), flag=wx.RIGHT|wx.BOTTOM, border=10)

我们在第四行中放置了两个按钮。 第三行留空,以便我们在wx.TextCtrl和按钮之间留出一些空间。 我们将“确定”按钮放入第四列,将“关闭”按钮放入第五列。 请注意,一旦我们向一个小部件应用了一些空间,它就会被应用于整行。 这就是为什么我们没有为“确定”按钮指定底部空间的原因。 细心的读者可能会注意到,我们没有在两个按钮之间指定任何空格。 也就是说,我们没有在“确定”按钮的右侧或“关闭”按钮的右侧放置任何空格。 在wx.GridBagSizer的构造器中,我们在所有小部件之间放置了一些空间。 所以已经有一些空间了。

  1. sizer.AddGrowableCol(1)
  2. sizer.AddGrowableRow(2)

我们必须做的最后一件事是使对话框可调整大小。 我们使第二列和第三行可增长。 现在我们可以扩大或缩小窗口。 尝试注释这两行,然后看看会发生什么。

wxPython 中的布局管理 - 图6

图:重命名窗口

新类示例

在下一个示例中,我们创建一个窗口,可以在 JDeveloper 中找到它。 这是用于在 Java 中创建新类的窗口。

new_class.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this example we create a new class layout
  6. with wx.GridBagSizer.
  7. author: Jan Bodnar
  8. website: www.zetcode.com
  9. last modified: April 2018
  10. """
  11. import wx
  12. class Example(wx.Frame):
  13. def __init__(self, parent, title):
  14. super(Example, self).__init__(parent, title=title)
  15. self.InitUI()
  16. self.Centre()
  17. def InitUI(self):
  18. panel = wx.Panel(self)
  19. sizer = wx.GridBagSizer(5, 5)
  20. text1 = wx.StaticText(panel, label="Java Class")
  21. sizer.Add(text1, pos=(0, 0), flag=wx.TOP|wx.LEFT|wx.BOTTOM,
  22. border=15)
  23. icon = wx.StaticBitmap(panel, bitmap=wx.Bitmap('exec.png'))
  24. sizer.Add(icon, pos=(0, 4), flag=wx.TOP|wx.RIGHT|wx.ALIGN_RIGHT,
  25. border=5)
  26. line = wx.StaticLine(panel)
  27. sizer.Add(line, pos=(1, 0), span=(1, 5),
  28. flag=wx.EXPAND|wx.BOTTOM, border=10)
  29. text2 = wx.StaticText(panel, label="Name")
  30. sizer.Add(text2, pos=(2, 0), flag=wx.LEFT, border=10)
  31. tc1 = wx.TextCtrl(panel)
  32. sizer.Add(tc1, pos=(2, 1), span=(1, 3), flag=wx.TOP|wx.EXPAND)
  33. text3 = wx.StaticText(panel, label="Package")
  34. sizer.Add(text3, pos=(3, 0), flag=wx.LEFT|wx.TOP, border=10)
  35. tc2 = wx.TextCtrl(panel)
  36. sizer.Add(tc2, pos=(3, 1), span=(1, 3), flag=wx.TOP|wx.EXPAND,
  37. border=5)
  38. button1 = wx.Button(panel, label="Browse...")
  39. sizer.Add(button1, pos=(3, 4), flag=wx.TOP|wx.RIGHT, border=5)
  40. text4 = wx.StaticText(panel, label="Extends")
  41. sizer.Add(text4, pos=(4, 0), flag=wx.TOP|wx.LEFT, border=10)
  42. combo = wx.ComboBox(panel)
  43. sizer.Add(combo, pos=(4, 1), span=(1, 3),
  44. flag=wx.TOP|wx.EXPAND, border=5)
  45. button2 = wx.Button(panel, label="Browse...")
  46. sizer.Add(button2, pos=(4, 4), flag=wx.TOP|wx.RIGHT, border=5)
  47. sb = wx.StaticBox(panel, label="Optional Attributes")
  48. boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)
  49. boxsizer.Add(wx.CheckBox(panel, label="Public"),
  50. flag=wx.LEFT|wx.TOP, border=5)
  51. boxsizer.Add(wx.CheckBox(panel, label="Generate Default Constructor"),
  52. flag=wx.LEFT, border=5)
  53. boxsizer.Add(wx.CheckBox(panel, label="Generate Main Method"),
  54. flag=wx.LEFT|wx.BOTTOM, border=5)
  55. sizer.Add(boxsizer, pos=(5, 0), span=(1, 5),
  56. flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT , border=10)
  57. button3 = wx.Button(panel, label='Help')
  58. sizer.Add(button3, pos=(7, 0), flag=wx.LEFT, border=10)
  59. button4 = wx.Button(panel, label="Ok")
  60. sizer.Add(button4, pos=(7, 3))
  61. button5 = wx.Button(panel, label="Cancel")
  62. sizer.Add(button5, pos=(7, 4), span=(1, 1),
  63. flag=wx.BOTTOM|wx.RIGHT, border=10)
  64. sizer.AddGrowableCol(2)
  65. panel.SetSizer(sizer)
  66. sizer.Fit(self)
  67. def main():
  68. app = wx.App()
  69. ex = Example(None, title="Create Java Class")
  70. ex.Show()
  71. app.MainLoop()
  72. if __name__ == '__main__':
  73. main()

这是一个更复杂的布局。 我们同时使用wx.GridBagSizerwx.StaticBoxsizer

  1. line = wx.StaticLine(panel)
  2. sizer.Add(line, pos=(1, 0), span=(1, 5),
  3. flag=wx.EXPAND|wx.BOTTOM, border=10)

该行用于分隔布局中的小部件组。

  1. icon = wx.StaticBitmap(panel, bitmap=wx.Bitmap('exec.png'))
  2. sizer.Add(icon, pos=(0, 4), flag=wx.TOP|wx.RIGHT|wx.ALIGN_RIGHT,
  3. border=5)

我们将wx.StaticBitmap放入网格的第一行。 我们将其放在行的右侧。

  1. sb = wx.StaticBox(panel, label="Optional Attributes")
  2. boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)

wxStaticBoxSizer类似于普通的wx.BoxSizer,但它在大小调整器周围添加了一个静态框。 我们将复选框放入静态框大小调整器中。

wxPython 中的布局管理 - 图7

图:新类窗口

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