一个典型的GUI程序的窗口界面中,一般是由各种控件(或者部件)组成,这些部件一般都会按一定的布局呈现在窗口中。布局方式可以分为绝对定位布局和相对定位布局,绝对定位布局中的控件不会随窗口的大小变化而做调整,相对布局则会根据窗口的尺寸对其中的控件布局进行调整,以更好地适应窗口的变化。在比较久远的一些GUI框架中,一般只支持绝对定位布局,比如微软的MFC框架,只支持绝对定位布局。绝对布局虽然使用方便,但有很大的局限性。一般现代GUI框架,无论是微软的.Net 框架,Andriod SDK 里的布局,wxWidgets, Qt等C++ 框架,都提供了布局管理功能,来提供更灵活的窗口布局。
PyQt5是QT5的Python封装,wxPython是wxWidgets的Python封装,因此你无论是在PyQt5还是在wxPython中,都提供了管理应用程序布局的功能模块。在wxPython中,可以使用绝对定位或者使用sizer来进行布局管理。
绝对定位布局
绝对布局是指在窗口中以像素为单位指定每个部件的位置和大小。绝对定位布局有几个明显的缺点:
- 如果我们调整窗口大小,部件的大小和位置不会改变。
- 在不同平台上,应用程序看起来都不同。
- 在应用程序中更改字体可能会破坏布局。
- 如果决定更改布局,则必须完全重做布局,这样做既繁琐又耗时,更容易出错。
在一些简单的测试程序,使用绝对布局可以快速演示某个功能,但是在大多数情况下,都使用sizer来进行布局管理。
尺寸调节器
尺寸调节器解决了绝对定位布局中提到的所有这些问题。wxPython提供了以下调节器:
- wx.BoxSizer
- wx.StaticBoxSizer
- wx.GridSizer
- wx.FlexGridSizer
- wx.GridBagSizer
使用尺寸调节器,我们可以在wxPython中实现满足各种要求的布局,在后续的文章中将对其做更详细的介绍。
绝对布局演示
在绝对布局示例中,我们在窗口中使用wx.StaticBitmap加载几幅图像,使用绝对位置放置在窗口中。当我们调整窗口的大小的时候,可以看到,图像的位置并不随窗口的尺寸变化而做调整,以适应窗口的变化。完整代码如下:
import wx
import os
class Example(wx.Frame):
def __init__(self, *args, **kwargs):
super(Example, self).__init__(*args, **kwargs)
self.SetTitle('实战wxPython: 绝对位置布局演示')
self.SetSize(480, 360)
self.InitUi()
self.Centre()
def InitUi(self):
self.panel = wx.Panel(self)
self.panel.SetBackgroundColour("gray")
self.LoadImages()
self.pythonLogo.SetPosition((10, 10))
self.wxpythonLogo.SetPosition((100, 10))
self.wxwidgetsLogo.SetPosition((20, 200))
def LoadImages(self):
imgPath = os.path.dirname(__file__)
self.pythonLogo = wx.StaticBitmap(self.panel, wx.ID_ANY,
wx.Bitmap(imgPath + '/python-logo.png', wx.BITMAP_TYPE_ANY))
self.wxpythonLogo = wx.StaticBitmap(self.panel, wx.ID_ANY,
wx.Bitmap(imgPath + '/wxpython.png', wx.BITMAP_TYPE_ANY))
self.wxwidgetsLogo = wx.StaticBitmap(self.panel, wx.ID_ANY,
wx.Bitmap(imgPath + '/wxwidgets-logo.png', wx.BITMAP_TYPE_ANY))
def main():
app = wx.App()
window = Example(None)
window.Show()
app.MainLoop()
if __name__ == '__main__':
main()
运行效果如下图所示:
wxPython绝对布局演示
本文知识点
- GUI程序为什么需要布局;
- 了解wxPython中的布局管理;
- 认识静态图像控件wx.StaticBitmap;
- 使用绝对定位布局。