一个典型的GUI应用程序可以抽象为:主界面(菜单栏、工具栏、状态栏、内容区域),二级界面(模态、非模态),信息提示(Tooltip),程序图标等组成。本篇根据作者使用PyQt5编写的一个工具,介绍如何使用PyQt5构建一个典型的GUI应用。
1. 主界面
QMainWindow类提供一个有菜单条、锚接窗口(例如工具条)和一个状态条的主应用程序窗口。主窗口通常用在提供一个大的*窗口部件(例如文本编辑或者绘制画布)以及周围菜单、工具条和一个状态条。QMainWindow常常被继承,因为这使得封装*部件、菜单和工具条以及窗口状态变得更容易。
菜单栏
创建菜单的代码如下:
self.addMenu = self.menuBar().addMenu("&添加")
self.addMenu.addAction(self.addAvatarAct)
self.addMenu.addAction(self.addAvatarSetAct)
self.addMenu.addAction(self.addAvatarDecorationAct)
self.modifyMenu = self.menuBar().addMenu("&修改")
self.modifyMenu.addAction(self.modifyAvatarAct)
self.modifyMenu.addAction(self.modifyAvatarSetAct)
self.settingMenu = self.menuBar().addMenu("&设置")
self.settingMenu.addAction(self.settingAct)
其中每个菜单项,关联一个QAction,定义了图标、菜单名、回调函数、快捷键等等,这里没有设置快捷键。
self.addAvatarAct = QAction(QIcon("res/ico/addAvatar.ico"), "&Add Avatar", self, triggered=self.addAvatar)
self.addAvatarSetAct = QAction(QIcon("res/ico/addAvatarSet.ico"), "&Add AvatarSet", self, triggered=self.addAvatarSet)
self.addAvatarDecorationAct = QAction(QIcon("res/ico/addAvatarDecoration.ico"), "&Add AvatarDecoration", self, triggered=self.addAvatarDecoration)
self.modifyAvatarAct = QAction(QIcon("res/ico/modifyAvatar.ico"), "&Modify Avatar or Decoration", self, triggered=self.modifyAvatar)
self.modifyAvatarSetAct = QAction(QIcon("res/ico/modifyAvatarSet.ico"), "&Modify AvatarSet", self, triggered=self.modifyAvatarSet)
self.settingAct = QAction(QIcon("res/ico/settingPath.ico"), "&路径", self, triggered=self.settingPath)
self.homeAct = QAction(QIcon("res/ico/home.ico"), "&首页", self, triggered=self.homePage)
说明:QAction类提供了一个可以同时出现在菜单和工具条上的抽象用户界面操作。
在图形用户界面应用程序中很多命令可以通过菜单选项、工具条按钮和键盘快捷键调用。因为同一个操作将会被执行,而与它的调用方法无关,并且因为菜单和工具条必须保持同步,所以提供一个操作这样的命令很有用。一个操作可以被添加到菜单和工具条中并且将会自动使它们同步。例如,如果用户按下“加粗”工具条按钮,“加粗”菜单项将会自动被选中。
QAction可以包含图标、菜单文本、快捷键、状态条文本、这是什么文本和工具提示。它们可以分别通过setIconSet()、setText()、setMenuText()、setToolTip()、setStatusTip()、setWhatsThis()和setAccel()来设置。
工具栏
创建工具栏的代码如下:
self.toolbar = self.addToolBar('Home')
self.toolbar.addAction(self.homeAct)
self.toolbar = self.addToolBar('AddAvatar')
self.toolbar.addAction(self.addAvatarAct)
self.toolbar = self.addToolBar('AddAvatarDecoration')
self.toolbar.addAction(self.addAvatarDecorationAct)
self.toolbar = self.addToolBar('AddAvatarSet')
self.toolbar.addAction(self.addAvatarSetAct)
self.toolbar = self.addToolBar('ModifyAvatar')
self.toolbar.addAction(self.modifyAvatarAct)
self.toolbar = self.addToolBar('ModifyAvatarSet')
self.toolbar.addAction(self.modifyAvatarSetAct)
工具栏项也需要关联一个QAction,可以和菜单项共用一个QAction,即一个QAction可以被关联到多个地方。
状态栏
设置状态栏,只需要:
self.statusBar().showMessage("数据加载完成")
第一次调用self.statusBar()获取工具栏时,会初始化工具栏实例,后面再次调用不会在创建新的实例。
程序图标
程序图标分为2个:程序窗口图标;执行文件的图标。
l setWindowIcon(QIcon(“res/ico/icon.ico”))设置程序窗口的图标
l 执行文件的图标,通过打包工具设置
2. UI布局
PyQt的布局系统提供了一个规定子窗口部件布局的简单的和强有力的方式。当你一旦规定了合理的布局,你就会获得如下利益:
l 布置子窗口部件。
l 最高层窗口部件可感知的默认大小。
l 最高层窗口部件可感知的最小大小。
l 调整大小的处理。
l 当内容改变的时候自动更新:
n 字体大小、文本或者子窗口部件的其它内容。
n 隐藏或者显示子窗口部件。
n 移去一些子窗口部件。
PyQt支持的布局方式有很多,如下表所示:
布局相关类为最小值并且伸缩因子为stretch直到布局末尾 网络布局网格布局(QGridLayout)顾名思义,将空间划分成多行多列的网络,然后通过addWidget、addItem将widget填充到指定的单元格(cell)。这个比较像网页中使用table布局的思路。下面的代码即创建上图中的网格布局: grid = QGridLayout() gridWidget = QWidget() 上述往网格中添加的widget都是占一个单元格的情况,其实还支持占用几个单元格。如下代码,往网格中的第二行、第一列添加一个widget,占用1行、2列: grid.addWidget(self.createDetail(), 1, 0, 1, 2) 网格布局默认是均分每列,为了更好的控制布局,QGridLayout为每列提供了最小宽度(setColumnMinimumWidth())、伸缩因子(setColumnStretch()),为每行提供了最小高度(setRowMinimumHeight())、伸缩因子(setRowStretch())。最小宽/高度很好理解,伸缩因子如下面代码,设置了第二列和三列的比例是1:2。 layout.setColumnStretch(1, 10) 3. 二级弹窗QDialog类是对话框窗口的基类。对话框窗口是主要用于短期任务以及和用户进行简要通讯的*窗口。QDialog可以是模态对话框也可以是非模态对话框。QDialog支持扩展性并且可以提供返回值。它们可以有默认按钮。 内置对话框内置常用的对话框有:QColorDialog、QErrorMessage、QFileDialog、QFontDialog、QInputDialog、QMessageBox、QProgressDialog、QTabDialog、QWizard。 内置的对话框提供了一些常用的功能,使用起来也必将遍历。编写该工具使用到了,选择文件、目录的对话框QFileDialog。 自定义对话框如果内置的对话框不能满足需求,可以自定义对话框(继承自QDialog)。如下定义了一个设置路径的对话框: class SettingDialog(QDialog): 使用对话框,只需要: dialog = SettingDialog() 4. 常用组件下面介绍编写工具过程中使用到的组件的一些注意事项。 QTableWidget列自适应如果有很多列,QTableWidget出出现水平滚动条,但是有不希望有滚动条可以通过设置列自适应方式: tw.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) 保证所以列都能显示,不会出现水平滚动条,这样有的单元格显示会被截断显示,如图中的"青年套装下装"-->"青年套装...",这时可以设置单元的tooltip提供完整显示的途径。 禁止编辑编写工具时,有要求QTableWidget展示出来的数据不能编辑,是通过以下方式实现: tw.setEditTriggers(QAbstractItemView.NoEditTriggers) QAbstractItemView还定义了其它的模式,如下表所示:
|