PyQt5 介绍与安装

一个强大的 UI 框架

Posted by Ethan on October 8, 2019

Hint 1 : 由于涉及到 Python, 所以需要有一定的 Python 基础。如果没学过也没有太大关系,因为相比于语法复杂,要求苛刻的C语言家族,Python 简单易学要求低,只需要一两天就可以掌握基础语法。

Hint 2 : 本教程前半部分十分简单,对于比较大佬的童鞋,可以直接从 PyQt5 使用思路与使用技巧 章节看起。

Hint 3: 本教程中标有 下划线 都是博主皮一下的文字,如果只希望看到正文内容的童鞋请自行忽略哈 ~

前言

由于大作业需要,在这里博主将简单介绍一个十分好用的 图形设计 框架 PyQt ,即 QtPython 下的实现。

PyQt 集 Qt 强大的图形显示功能 和 Python 的 简洁优雅 ,再加上我们曾经 有过 Qt 开发的经验 尽管早就忘掉一大半 ,这使得 PyQt 成为一个十分强大易用的图形开发 完成大作业 工具。

下面我将向大家介绍 PyQt 的基本用法~

Introduction:简介

Pyqt5 是 QtPython 下 的实现

没错,就是那个支配我们一个小学期的 Qt

它主要有如下几个方面的特点:

  1. 功能强大

    ​ 一个模块底下有 620 个类和 6000 个函数和方法,可以满足最异想天开的图形要求。(写出bug时,一定要坚信是自己写错了,而不是框架有问题,它真的很强的…)

  2. 良好的生态环境

    ​ 另一方面,它有着 Python 十分良好的生态环境作为支持,可以调用 Python 中十分好用的一些模块,可以有效减少我们需要写的代码量 (能用别人的函数,当然不去自己亲手写bug啦)。

  3. 跨平台

    ​ 同时,它还这是一个跨平台的工具包,可以运行在所有主要的操作系统上。

说完 吹完 PyQt,下面我们就来看看如何安装 PyQt5 以及跑通我们第一个例程。

Installaion & configuration: 安装与环境配置

程序猿最烦的一件事,就是配置环境。但是我们所介绍的 PyQt5 的配置却异常简单。

下面将介绍 VSCode + PyQt5 + QtDesigner 的环境配置。

Note 1:如果原来用的是 PyCharm 等 IDE 的话,与本教程的差别只在于需要对 PyCharm 做一些额外配置。具体方法需要自行百度~

Note 2:这里默认是已经下载过 Python 的 话说学 Python 的时候怎么可能不下 Python 呢

VSCode 下载与配置

下载:直接无脑👉 官网 下载,具体过程不再详细叙述。

配置:只需安装 Python 插件以支持 Python 编写。

1569750744235

最后:利用简单的 print Hello World 来验证是否安装成功,在这个过程中可以熟悉 VSCode 的使用~

由于以上内容都比较 easy,所以就不再多费笔墨~

PyQt5 和 QtDesigner 下载

首先,安装 PyQt5

打开命令行,输入以下命令

pip install PyQt5 -i https://pypi.douban.com/simple

这句命令的含义为:使用 Python 的模块管理工具 pip 安装 PyQt5 模块。

这里的安装来源使用了一个国内的镜像,以加快下载速度(https://pypi.douban.com/simple )

下载过程如下图所示:

1569751761798

下载完成!

1569751792776

提示:如果中间下载出现“卡壳”,可以多按几下 向下 的方向键 来刷新屏幕~

其次,安装 QtDesigner

在安装完PyQt 之后在命令行中输入

pip install PyQt5-tools -i https://pypi.douban.com/simple

和上面类似,这一步是在用 pip 安装 PyQt5 所需要的一系列工具。

在这些工具中,我们主要需要的是 Qt 的 Designer。

下载完成后建议打开下载位置(具体位置见下),然后将 Designer 固定到桌面上 ~

最后,将 pyqt5-tools 的安装位置 添加到 全局变量(Path) 中。

比如博主的安装位置为

D:\python3.6\Lib\site-packages\pyqt5_tools

找不到类似位置的童鞋可以先找找自己计算机中安装的 Python 位置(可以从原先的 Path 变量中看出),然后再添加 👆 类似的路径。

至此,Pyqt5 就安装完了,整个过程只需要花费 不到 20 分钟时间 。 然后我们就可以开始用 PyQt 完成我们的第一个小程序。

开始享受 PyQt 的简单易用吧 ~

Hello,PyQt!

每学习一门崭新的语言,或者熟悉一种陌生的框架时,需要做的最为重要的事情,就是 “Hello World” 。

Talk is cheap, Let‘s code !

首先利用 vscode 新建一个文件夹,然后新建 hello_pyqt.py 文件。

1570450796175

要使用 PyQt ,首先需要将 PyQt 模块和 sys 模块(用于系统管理)导入

import sys
import PyQt5 
from PyQt5 import QtWidgets 
from PyQt5.QtWidgets import QApplication

然后 为了系统管理,需要写一段用于系统管理的代码:

app = QtWidgets.QApplication(sys.argv)

"""
Put your code here 
"""

sys.exit(app.exec())

如果还对我们C++小学期有一些印象的话,对这一段代码比较容易理解。第一句是为了 接收程序运行时的参数(就像我们计网中使用到的 ping -r 中的 -r 参数),最后一句是为了 正式开始 运行整个程序,并在程序结束时给系统提供运行结果(0或是1,代表是否正常退出)。

上面的两步基本上是写每一个程序都需要完成的两步,可以看成是必须要写的 模板

然后在 Put your code 处我们才正式开始写我们自己的代码。对于本教程,我们接下来将写一个简单的窗口,并将其命名为 “hello, pyqt5” 。代码如下:

widget = QtWidgets.QWidget()
widget.resize(360, 360)
widget.setWindowTitle("hello, pyqt5")
widget.show()

由于这里的思路和小学期写 C++ 的思路是一样的,所以就不再叙述啦 ~ 整体代码如下

import sys
import PyQt5 
from PyQt5 import QtWidgets 
from PyQt5.QtWidgets import QApplication
 
app = QApplication(sys.argv)

"""
Put your code here 
"""

widget = QtWidgets.QWidget()
widget.resize(360, 360)
widget.setWindowTitle("hello, pyqt5")
widget.show()

sys.exit(app.exec())

最终的运行结果基本如下所示:

1570451988620

如果完成了上一步,恭喜,你的 PyQt 安装正常 ~

—————————— 难度分界线 ——————————

PyQt5 的使用思路与使用技巧

上面的 Hello pyqt5 程序,相比于我们本次大作业所需要写的程序,实在是太过简单。

所以,下面就将仔细讲讲 如何用 PyQt5 **写我们本次 **大作业 所需要的 UI 程序。

Frame:程序框架

大作业的 UI程序 框架大致分为三段,即

  1. 导入模块段
  2. 将我们所要写的 UI 包装为一个 Class 的段
  3. 主代码运行段 (后面将简单解释为什么要写第三段)

基本框架如下所示:

## import modules needed 

#  ...

## use your UI as a class 

#  ... 

## start code 

#  ...

模块导入段 ,我们导入我们需要使用到的模块,包括

  • PyQt 的相关模块 (如 sys 和 PyQt5)
  • 其他辅助模块
  • 自己的算法模块【大作业核心】

如下所示:

## import modules needed 

# Pyqt 5 modules 

import sys
import PyQt5 
from PyQt5.QtWidgets import QDialog 
from PyQt5.QtWidgets import QApplication
from PyQt5.uic import loadUi 

# other modules

# ... 

# then import your algorithm here 
import myAlgorithm

接下来才是我们 写UI的重点 敲黑板 ,即如何将整个 UI 用一个类包装起来。这一段的编写主要包括如下三步:

  1. 完成 __init__ 函数
  2. 完成 slotXXX && xxxEvent 函数 (即槽函数和事件函数)
  3. 完成其他函数

如下代码所示:

## use your UI as a class 

class myUI(QDialog):
	def __init__(self,*args): 
		# ...
        
    def slotXXX(self): 
        # ...
        
    def xxxEvent(self): 
        # ... 
        
    def otherFunc(self): 
        # ... 

Note:可能很多人有点奇怪,为什么博主一定要强调用一个类来包装。其实,这样做主要是为了简化后续的开发和修改过程,为大家的大作业剩下更多的时间可以用于算法改进。

1. __init__ 函数

对于初始化 __init__ 函数,写的大致思路如下所示:

def __init__(self,*args): 
    # init ui 
    
    super(myUI,self).__init__(*args)
    loadUi('./myui.ui')
    
    # other init configuration 
    
    # ... 
    
    # connect slot
    
    self.xxxWidgets.signal.connect(self.slotXXX)
  • init ui 部分 — super 函数:

    ​ 这里我使用了一个 QDialog 作为我的 UI 的父类,所以需使用super 函数进行继承

  • init ui 部分 — loadUi 函数:

    ​ PyQt5 编写程序的整体过程,需要首先使用 Qt Designer 将大致的界面设计出来,然后保存为 *.ui 文件。之后在类的初始化函数中,利用 loadUi 函数将其导入为我们的代码所用。

  • other init configuration 部分:

    ​ 初始化其他需要在 UI 中用到的 状态变量

  • connect slot 部分:

    ​ 在这个部分,我们将连接信号与槽函数。每一次连接我们将都以 👇 函数进行。

     self.xxxWidgets.signal.connect(self.slotXXX)
    

    ​ 其中,xxxWidgets 为我们在 .ui 文件中所设置的组件(Widget)的名称,signal 为对应组件的信号函数名称,self.slotXXX 为我们将在后面编写的,属于 myUI 的类方法(由于这些类方法将用为槽函数,所以我们统一在函数名前加 slot以标识)。

2. slotXXX & xxxEvent 函数
    def slotXXX(self): 
        # ...
        
    def xxxEvent(self): 
        # ... 

其中:

  • slotXXX 函数:为我们自己定义的槽函数,本质是 myUI 的一个类方法(class method) ,只不过为了清楚的标识其为槽函数,故其命名以 slot 开头。
  • xxxEvent 函数:为已经在 QDialog 定义过 的函数,所以:
    1. 对应于特定的 Event ,事件函数的 名称唯一
    2. Event 函数都需要我们在 myUI 类下 重新实现 ,即按照自己的想法编写函数

而最后的 函数开始段 ,大致格式如下所示:

## start code 

if __name__ == "__main__":
    #init 
    
    app = QApplication(sys.argv)
    
    #begin 
    
    sys.exit(app.exec_())

Note: 这里的 __name__ 实际上为 python 文件的一个全局变量,对于 python 文件本身可见。如果该变量在代码被执行时设置为 “__main__” ,则代表系统从该 *.py 文件运行整个工程(project)。

所以,整体程序框架大致如下所示:

## import modules needed 

# Pyqt 5 modules 

import sys
import PyQt5 
from PyQt5.QtWidgets import QDialog 
from PyQt5.QtWidgets import QApplication
from PyQt5.uic import loadUi 

# other modules

# ... 

# then import your algorithm here 

import myAlgorithm


## use your UI as a class 

class myUI(QDialog):
	def __init__(self,*args): 
    	
        # init ui 
    	
        super(myUI,self).__init__(*args)
    	loadUi('./myui.ui')
    
    	# other init configuration 
    	
        # ... 
    
    	# connect slot 
    	self.xxxWidgets.signal.connect(self.slotXXX)
        
    def slotXXX(self): 
		
        # ...
        
    def xxxEvent(self): 
        
        # ... 
        
    def otherFunc(self): 
        
        # ... 
        
        
## start code 

if __name__ == "__main__":
    
    #init 
    
    app = QApplication(sys.argv)
    
    #begin 
    
    sys.exit(app.exec_())

可以利用上面的程序框架,再加上自己的想法,完成本次大作业中 UI 部分的设计。

Sample Code : 样例代码

在了解过代码的整体框架后,剩下的工作只是根据个人需要来使用 Qt 框架。在这个过程中,难免会出现各种各样的问题。

一般来说,问题主要是由两种原因导致的:

  1. Qt 框架 使用不熟练

    ​ 这个问题其实比较好解决,只需要多 google(需要翻 GFW 哈),多看这里的 官方文档

  2. 程序逻辑 不大清晰

    ​ 在具体设计的时候,为了解决这个问题,博主提供了一份自己曾经使用 PyQt5 写过的,用于项目“眼动控制小车” 的上位机代码,具体链接在 👉 这里 。有什么不懂的,也欢迎来找博主交流 ~

希望大家都能顺利完成自己的 UI 设计!

后记

可能写的有些简单,这也是因为自己的时间关系,请大家见谅

也希望喜欢的童鞋能贡献下你们的 star ⭐️ ~