51dev.com IT技术开发者社区

51dev.com 技术开发者社区

痞子衡嵌入式:超级好用的可视化PyQt GUI构建工具(Qt Designer)

Pythonphp学习阅读(11)2019-10-10 收藏0次评论


  大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是pyqt gui构建工具qt designer

  痞子衡开博客至今已有好几年,一直以嵌入式开发相关主题的文章为主线,偶尔穿插一些其他技术或工具的介绍,前段时间因为要做一个跟恩智浦mcu启动相关的上位机工具 nxp-mcubootutility,网上搜索对比了几个python下的gui框架,最终选择了wxpython这个成熟稳定的gui库,从而接触到wxformbuilder这个配套wxpython使用的gui构建工具。苦于网上关于该构建工具的中文资料不多,所以根据自己使用经验写了一篇 极易上手的可视化wxpython gui构建工具(wxformbuilder),没想到该篇博客很受欢迎,居然目前是痞子衡博客里阅读量最高的一篇博客,而且也是搜索 wxformbuilder 关键字出来的中文结果排名第二位的链接,真是万万没想到。

  wxpython框架虽然成熟稳定,但是相对最近更火的pyqt框架来说,还是显得古老了一些,控件风格不符合现代审美观,因此痞子衡决定学习一下pyqt的用法,感受下pyqt做出来的界面效果到底如何。根据wxpython学习经验,当然首先要从pyqt的可视化gui构建工具qt designer开始下手,因此便有了本篇博客。

一、qt designer工具背景

  qt designer从名字上来看显然就是久负盛名的跨平台gui库qt的配套设计工具。qt库本身是c++语言实现的;riverbank公司用python语言对qt做了一层封装,封装后便成了python版gui库pyqt(目前最新的版本是pyqt5);下面是这两个gui库的官方主页:

  • qt项目官方网站:
  • pyqt项目官方主页:

  qt的各种ui控件功能均是通过class来实现的,这个链接 列出了qt里的所有class。pyqt5其用法基本与qt一致,这个链接 https://www.riverbankcomputing.com/static/docs/pyqt5/module_index.html#ref-module-index 列出了pyqt5里所有的modules,其中用于设计界面最常用的便是 qtwidgets 模块。

  在qt官网的tools下面可以看到所有qt相关的工具,在ui design tools下面可以找到qt designer,可见qt designer是用于设计gui界面的工具之一。由于痞子衡介绍的pyqt5下的gui构建工具,因此本文的qt designer并不是直接在qt官网下载安装的,具体安装方法详见下一章节。

二、qt designer快速上手

  使用qt designer去设计gui界面可以不用掌握pyqt5里的各个控件class的具体用法,你只需要在qt designer软件里添加这些控件即可,下面痞子衡将简介qt designer的用法:

2.1软件安装

  简单了解pyqt5的module和class便可以开始设计gui界面,首先得安装qt designer,在安装完python3之后(痞子衡安装的是python 3.6),借助python36scripts下的pip.exe工具来分别安装pyqt5和qt designer,命令见如下主页:

  • pyqt5安装: https://pypi.org/project/pyqt5/
  • qt designer安装:

  安装完成之后打开python36libsite-packagespyqt5_toolsdesigner.exe,这便是qt designer。

2.2软件界面

  打开qt designer可见到如下界面,界面主要分为四大区:项目区、控件区、编辑区、属性区。软件使用起来非常简单,就是在【控件区】里点击添加需要的控件,这些控件的效果会在【编辑区】里实时显示,并在【属性区】这些控件的属性,【项目区】用于显示控件间的层级关系。

2.3基础布局

  让我们开始创建一个gui的基础框架,基础框架包括:container(局部外围轮廓)、layout(内部控件区)、menubar(顶部菜单栏)、statusbar(底部状态栏)。
  第一步是添加一个container(此处选择常用的frame),这是gui的轮廓基础,有了frame之后还需要在frame里添加layout(此处选择竖排样式),用于规范后续控件的排列样式。默认gui即有menubar和statusbar。

2.4多种控件

  基础布局搞定之后,接下来便是在layout里添加控件,pyqt5支持的控件非常丰富,其中比较常用的是如下几个:各种button(按钮)、label(静态显示文本框)、text edit(输入输出文本框)、check box(选中框)、各种slider(滑动条)等。由于前面痞子衡选择的是verticallayout,因此你会看到控件们都是竖着排的。

2.5控件属性

  添加了所有控件之后,下一步便是分别设置控件的属性,进一步调整控件。痞子衡以push button属性为例,痞子衡勾选了如下3项比较重要的属性设置,分别是objectname(button在后续python代码的对象名,一般需要按其功能修改,修改后使得代码阅读/修改起来更直观)、geometry(设置button的尺寸与位置,如果是放在layout里,则受限于layout不可设置)、text(button在gui里显示的标签名,此处是pushbutton,也需要按其功能修改,方便用户使用软件)。

2.6保存为xml代码(工程文件)

  当gui界面布局全部完成之后,需选择file->save as保存为.ui文件,该文件既是qt designer的工程文件也是最终生成的gui xml代码文件,痞子衡保存在了my_win.ui文件里。

2.7转换成python代码

  虽然保存的my_win.ui文件里是可以直接在python代码里被加载使用的,但是更好的办法是直接将.ui文件转换成相应的.py文件。需要借助 python36scriptspyuic5.exe工具,命令如下:

pyuic5 - o my_win.py my_win.ui

  转换成功后,让我们打开my_win.py文件,可以简单看一下这个my_win.py里的内容,代码里首先import了pyqt5相关库,并定义了名为ui_mainwindow的class,这个class主要包含两个函数setupui()和retranslateui()。setupui()里初始化了各个控件成员self.xx,这与我们在qt designer里添加控件是对应的。

# -*- coding: utf-8 -*-

# form implementation generated from reading ui file '.my_win.ui'
#
# created by: pyqt5 ui code generator 5.11.3
#
# warning! all changes made in this file will be lost!

from pyqt5 import qtcore, qtgui, qtwidgets

class ui_mainwindow(object):
    def setupui(self, mainwindow):
        mainwindow.setobjectname("mainwindow")
        mainwindow.resize(603, 448)
        self.centralwidget = qtwidgets.qwidget(mainwindow)
        self.centralwidget.setobjectname("centralwidget")
        self.frame = qtwidgets.qframe(self.centralwidget)
        self.frame.setgeometry(qtcore.qrect(100, 80, 361, 211))
        self.frame.setframeshape(qtwidgets.qframe.styledpanel)
        self.frame.setframeshadow(qtwidgets.qframe.raised)
        self.frame.setobjectname("frame")
        self.verticallayoutwidget = qtwidgets.qwidget(self.frame)
        self.verticallayoutwidget.setgeometry(qtcore.qrect(30, 20, 160, 172))
        self.verticallayoutwidget.setobjectname("verticallayoutwidget")
        self.verticallayout = qtwidgets.qvboxlayout(self.verticallayoutwidget)
        self.verticallayout.setcontentsmargins(0, 0, 0, 0)
        self.verticallayout.setobjectname("verticallayout")
        self.pushbutton = qtwidgets.qpushbutton(self.verticallayoutwidget)
        self.pushbutton.setenabled(true)
        self.pushbutton.setobjectname("pushbutton")
        self.verticallayout.addwidget(self.pushbutton)
        self.label = qtwidgets.qlabel(self.verticallayoutwidget)
        self.label.setobjectname("label")
        self.verticallayout.addwidget(self.label)
        self.textedit = qtwidgets.qtextedit(self.verticallayoutwidget)
        self.textedit.setobjectname("textedit")
        self.verticallayout.addwidget(self.textedit)
        self.checkbox = qtwidgets.qcheckbox(self.verticallayoutwidget)
        self.checkbox.setobjectname("checkbox")
        self.verticallayout.addwidget(self.checkbox)
        self.horizontalslider = qtwidgets.qslider(self.verticallayoutwidget)
        self.horizontalslider.setorientation(qtcore.qt.horizontal)
        self.horizontalslider.setobjectname("horizontalslider")
        self.verticallayout.addwidget(self.horizontalslider)
        mainwindow.setcentralwidget(self.centralwidget)
        self.menubar = qtwidgets.qmenubar(mainwindow)
        self.menubar.setgeometry(qtcore.qrect(0, 0, 603, 21))
        self.menubar.setobjectname("menubar")
        mainwindow.setmenubar(self.menubar)
        self.statusbar = qtwidgets.qstatusbar(mainwindow)
        self.statusbar.setobjectname("statusbar")
        mainwindow.setstatusbar(self.statusbar)

        self.retranslateui(mainwindow)
        qtcore.qmetaobject.connectslotsbyname(mainwindow)

    def retranslateui(self, mainwindow):
        _translate = qtcore.qcoreapplication.translate
        mainwindow.setwindowtitle(_translate("mainwindow", "mainwindow"))
        self.pushbutton.settext(_translate("mainwindow", "pushbutton"))
        self.label.settext(_translate("mainwindow", "textlabel"))
        self.checkbox.settext(_translate("mainwindow", "checkbox"))

三、使用qt designer生成的代码

  前面已经使用qt designer生成gui界面类ui_mainwindow并保存在my_win.py文件中,此时需要创建一个主函数文件去调用ui_mainwindow,下面是痞子衡创建的main_win.py中的代码:

import sys
from pyqt5.qtwidgets import qapplication, qmainwindow
# 导入my_win.py中内容
from my_win import *

# 创建mainwin类并传入ui_mainwindow
class mainwin(qmainwindow, ui_mainwindow):
    def __init__(self, parent=none):
        super(mainwin, self).__init__(parent)
        self.setupui(self)

if __name__ == '__main__':
    # 下面是使用pyqt5的固定用法
    app = qapplication(sys.argv)
    main_win = mainwin()
    main_win.show()
    sys.exit(app.exec_())

3.1触发事件与响应

  有了button,我们肯定希望其能与一个响应函数相联系起来,此处痞子衡定义了showmessage()函数,并且将showmessage()与pushbutton绑定起来,点击button便会执行一次这个showmessage()函数。代码如下:

class mainwin(qmainwindow, ui_mainwindow):
    def __init__(self, parent=none):
        super(mainwin, self).__init__(parent)
        self.setupui(self)
        # 将响应函数绑定到指定button
        self.pushbutton.clicked.connect(self.showmessage)

    # button响应函数
    def showmessage(self):
        self.textedit.settext('hello world')

  最后让我们测试一下这个gui软件,在命令行下运行main_win.py

ps d:my_git_repo> python .main_win.py

  至此,pyqt5 gui构建工具qt designer痞子衡便介绍完毕了,掌声在哪里~~~

参考资料

  1. 使用pyqt来编写第一个python gui程序
  2. pyqt5速成教程-2 qt designer介绍与入门

以上就是痞子衡嵌入式:超级好用的可视化PyQt GUI构建工具(Qt Designer)的全部内容,请多关注【51DEV】IT技术开发者社区。