Skip to content

PyQt6

PyQt6 是一个Python的GUI库,它基于Qt5,并且使用PySide6作为底层库。

PyQt6 Digia 公司的 Qt 程序的 Python 中间件。Qt库是最强大的GUI库之一。PyQt6的官网:www.riverbankcomputing.co.uk/news。PyQt6是由Riverbank Computing公司开发的。

PyQt6 是基于 Python 的一系列模块。它是一个多平台的工具包,可以在包括Unix、Windows和Mac OS在内的大部分主要操作系统上运行。PyQt6 有两个许可证,开发人员可以在 GPL 和商业许可之间进行选择。

使用 - 安装

sh
$ pip install PyQt6

我们可以使用 pip 工具安装 PyQt6。除此之外,还可以安装 PyQt6-tools,使用 designer 设计师软件构建窗体页面,然后使用 PyUIC6 将 .ui 文件转换为 PyQt6 的代码。

shell
pip install PyQt6-tools

这两步若下载缓慢,可使用 pip install PyQt6 PyQt6-tools -i https://mirrors.aliyun.com/pypi/simple 安装。

有时,安装可能会遇到如下的错误。

 Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... error
  error: subprocess-exited-with-error

  × Preparing metadata (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [26 lines of output]

这里可利用 StackOverflow上一个大神提供的方案解决。

  1. 从pypi下载该PyQt6-tools,链接为 https://pypi.org/project/PyQt6/#files 。下载 Windows 版本,如 PyQt6-6.4.1-cp37-abi3-win_amd64.whl 。
  2. 然后从pypi下载PyQt6-Plugins,链接为 https://pypi.org/project/pyqt6-plugins/#files 。下载 Windows 版本,如 pyqt6_plugins-6.1.0.2.2-cp39-cp39-win_amd64.whl 。
  3. 用WinRar (或类似的) 打开后一个文件,然后依次打开 "pyqt6_plugins-xxx.dist-info",用文本编辑器打开 METADATA 文件。
  4. 找到一行:"Requires-Dist: pyqt6(==6.1.0)"或类似的,并更改为"Requires-Dist: pyqt6"。保存文件。
  5. 最后手动安装这两个文件,先安装第一个,再安装第二个,命令为 pip install 文件名

源地址:https://stackoverflow.com/questions/72060996/cannot-install-pyqt6-tools-in-python-3-11-on-windows

了解 - PyQt6 模块

PyQt6 类是由一系列模块组成的,包括如下的模块:

  • QtCore
  • QtGui
  • QtWidgets
  • QtDBus
  • QtNetwork
  • QtHelp
  • QtXml
  • QtSvg
  • QtSql
  • QtTest

使用 - 第一个 PyQt6 窗体

先放代码。

python
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QMessageBox, QPushButton, QHBoxLayout, QWidget

app = QApplication([])

central_widget = QWidget()
window = QMainWindow()
window.setCentralWidget(central_widget)

button = QPushButton()
button.setText("点击我展示一个提示小窗口。")
button.clicked.connect(lambda: QMessageBox.information(window, "提示", "这是一个提示小窗口。"))

layout = QHBoxLayout(central_widget)
layout.addWidget(button)

window.show()
sys.exit(app.exec())

这段代码首先导入必要的模块和函数,然后创建了一个应用程序对象。PyQt6和很多框架一样,都需要在最开始创建一个应用程序对象,然后执行应用,窗体的有关功能才能执行。接下来就是创建一个窗体对象,这里窗体使用的是 QMainWindow,日常开发中如果窗体组件过多,推荐使用 QMainWindow。

接下来就是向窗体添加控件,这里添加了按钮,并且为了使按钮居中,使用 QHBoxLayout 布局,并且将按钮添加到布局中。

然后为按钮添加事件监听,当按钮被点击时,会弹出一个提示框。button.clicked 是一个函数,这个函数有一个 connect 方法,可以将按钮的点击事件连接到一个函数上。这里的点击事件就叫槽,函数就叫槽函数。

最后就是显示窗体和执行应用,由于 PyQt6 的应用对象 QApplication 是单例的,所以这里直接使用 sys.exit(app.exec())

使用 - 使用设计师软件设计窗体

若前面你根据我的教程安装了 PyQt6-tools 软件包,你可以在 PyQt6-tools 中找到一个名为 designer 的软件,这个软件可以设计窗体,然后生成对应的代码。

如果你使用 PyCharm 开发,使用 venv 作为虚拟环境,使用 pip 作为软件包管理工具,你可以在 <虚拟环境>/Lib/site-packages/qt6-Applications/Qt/bin/ 找到 designer.exe,它就是这里介绍的设计师软件。

这里简单介绍一下它的使用方法。

刚启动时,弹出一个引导界面,提示你要创建什么样的窗体,共有五个选项,也可以在这里找到已经保存的设计师文件。这里选择MainWindow。

默认创建的 MainWindow 包含一个菜单栏和一个导航栏。

创建完成后,左边的是组件列表,可以选择我们需要的组件,前面的 QPushButton 就在其中。中间的就是窗体预览和编辑处。

右边分为三部分,上面的是组件树,通过嵌套关系,我们就可以看出组件之间的层级关系。中间部分是属性管理器,它为我们展示了组件的所有属性,比如大小、文字、字体等,且支持编辑。下面是信号和槽管理器,以及资源管理器。

设计完主窗体后,点击菜单栏中的保存按钮,将 MainWindow.ui 文件保存到本地。

生成了 .ui 文件,还需要将 .ui 文件转换为可执行的 .py 文件,这里需要使用的一款工具就是 PyUIC6。

shell
pyuic6 -x MainWindow.ui -o MainWindow.py

执行这个命令后,就可以看到 MainWindow.py 文件了,运行此文件就可以看到窗体了。

使用 - 认识组件

可以看到,所有控件都继承自 QFrame,而 QFrame 继承自 QWidgets,QWidgets 的属性如大小、背景颜色、字体等,这些组件也都有,因此这里统一介绍一下比较常用的一些属性。

属性说明
enabled是否启用组件,不可用的组件会显示为灰色,并且不可操控
geometry组件的大小和位置,顺序依次是X、Y、宽度和高度。PyQt6的坐标系是从左上角开始的
minimumSize、maximumSize组件/窗体宽度和高度的最大值和最小值
styleSheet设定组件的样式表

这些属性为私有属性,若我们需要获取或改变这些属性,需要调用对应的 getter 或 setter 方法,如 button.setEnabled(True)

每个继承自 QWidget 类的控件,因其独特的功能,也会有属于自己的方法或属性,这些将在接下来的章节中介绍。

使用 - 信号与槽机制

Qt 中信号与槽就是事件监听的意思。

由于很多组件都继承自 QWidget,因此它们有一些公共的信号,但不常用。

这里虽然没有介绍具体的控件,但还是以按钮为例,介绍一下最常用的,按钮的“点击”信号如何和槽函数关联。

python
button.clicked.connect(function)

这里的 button 为 QPushButton 的实例,QPushButton 是一个可点击的按钮。

在 Qt 设计师软件中,依次点击导航栏上的【编辑】 - 【编辑信号/槽】,切换到此模式,然后点击按钮,并按住,拖拽出来,即可新建一个信号。

随后在弹出的对话框中,选中 clicked() 信号。这时候可以看到右侧没有任何槽函数,我们可以勾选“显示从 QWidget 继承的信号和槽”,并将 clicked()close() 函数关联。

使用 PyUIC6 转换成 Python 代码后,便可看到信号与槽关联的代码片段,大概为:

python
self.pushButton.clicked.connect(MainWindow.close)

这里是将两个函数关联起来,clicked是一个函数,MainWindow.close也是一个函数。若我们自定义函数时,也需要传递函数对象。

槽函数亦可以解除关联,可以调用组件对象的 disconnect() 方法。

组件 - 按钮

按钮是 Qt 中的一类大组件,常用的有点击按钮、单选按钮、复选框,对应的类分别为 QPushButton、QRadioButton、QCheckBox。它们都继承自 QAbstractButton,所以有一些公共的属性和方法(继承自 QWidgets 的属性和方法在这里不再重复)。

属性或方法说明
text()setText(text)获取或设置按钮的显示文本
isChecked()setChecked()isCheckable()setCheckable()获取或设置按钮的选中状态,QPushButton不可用

它们的常用信号如下:

信号说明
clicked按钮被点击时触发
toggled按钮选中状态被改变时触发
pressedreleased按钮被按下和释放时触发
stateChangedQCheckBox的选中状态被改变时触发,和 toggled 信号基本一致

示例代码:

python
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QRadioButton, QCheckBox, QVBoxLayout, QWidget, QMessageBox

app = QApplication([])

# 创建主窗口
window = QMainWindow()

# 创建中心部件,并设置为主窗口的中心部件
central_widget = QWidget()
window.setCentralWidget(central_widget)

# 创建按钮
button = QPushButton("点击我")
button.clicked.connect(lambda: QMessageBox.information(window, "按钮", "您点击了按钮"))

# 创建单选按钮
radio_button = QRadioButton("选择我")
radio_button.toggled.connect(lambda checked: print("单选按钮被选中" if checked else "单选按钮未选中"))

# 创建复选框
check_box = QCheckBox("勾选我")
check_box.stateChanged.connect(lambda state: print("复选框被选中" if state else "复选框未选中"))

# 创建垂直布局并设置为中心部件的布局
layout = QVBoxLayout(central_widget)
layout.addWidget(button)
layout.addWidget(radio_button)
layout.addWidget(check_box)

# 显示窗口
window.show()

# 运行应用程序
sys.exit(app.exec())

这里还需要介绍一下单选按钮如何实现互斥的操作,答案是将它们加入到按钮组 QButtonGroup 中,且可以默认选中一个单选按钮。

python
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QRadioButton, QCheckBox, QVBoxLayout, QWidget, QMessageBox, QButtonGroup

app = QApplication([])

# 创建主窗口
window = QMainWindow()

# 创建中心部件,并设置为主窗口的中心部件
central_widget = QWidget()
window.setCentralWidget(central_widget)

# 创建单选按钮
radio_button1 = QRadioButton("选择我")
radio_button2 = QRadioButton("选择另一个")

# 创建一个按钮组来管理单选按钮
button_group = QButtonGroup()  # 创建QButtonGroup实例
button_group.addButton(radio_button1)  # 将第一个单选按钮添加到组中
button_group.addButton(radio_button2)  # 将第二个单选按钮添加到组中

# 创建垂直布局并设置为中心部件的布局
layout = QVBoxLayout(central_widget)
layout.addWidget(radio_button1)
layout.addWidget(radio_button2)

# 显示窗口
window.show()

# 运行应用程序
sys.exit(app.exec())

使用 - 展示控件 QLabel

QLabel 是 Qt 库中最基础的文本和图像展示控件之一。它可以用来显示纯文本或富文本,甚至可以用来展示图片。QLabel 非常灵活,可以根据需要调整其外观和行为。

QLabel的常用属性:

属性和方法说明
setText()text()设置或获取标签的文本内容
setAlignment(alignment)设置标签文本的对齐方式
setStyleSheet(style)设置标签的样式表

示例代码:

python
import sys
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QPixmap
from PyQt6.QtWidgets import QApplication, QLabel, QMainWindow, QVBoxLayout, QWidget

app = QApplication([])

# 创建主窗口
window = QMainWindow()

# 创建中心部件,并设置为主窗口的中心部件
central_widget = QWidget()
window.setCentralWidget(central_widget)

# 创建 QLabel 显示文本
text_label = QLabel("欢迎使用 PyQt6!")
text_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
text_label.setWordWrap(True)

# 创建 QLabel 显示图片
image_label = QLabel()
pixmap = QPixmap("example.png")  # 假设 example.png 存在于当前目录下
image_label.setPixmap(pixmap)
image_label.setScaledContents(True)

# 创建垂直布局并设置为中心部件的布局
layout = QVBoxLayout(central_widget)
layout.addWidget(text_label)
layout.addWidget(image_label)

# 显示窗口
window.show()

# 运行应用程序
sys.exit(app.exec())

使用 - 布局

在 PyQt6 中,布局是用来管理窗口或控件内部的空间分配和控件排列的一种机制。使用布局可以帮助我们更容易地管理控件的位置和大小,同时也能保证控件在不同屏幕尺寸和分辨率下都能正确显示。Qt 提供了几种常见的布局管理器,包括 QHBoxLayout 和 QVBoxLayout,它们分别用于水平和垂直方向上的控件排列。

QHBoxLayout 是一个布局管理器,它负责在其容器内从左到右水平排列控件。当你希望控件横向排列时,可以使用 QHBoxLayout。

QVBoxLayout 则是在垂直方向上排列控件,从上到下。适合于需要垂直堆叠控件的情况。

常用方法:

  • addWidget(widget):将一个控件添加到布局中。
  • addStretch(stretch=0):添加一个拉伸空间,stretch 参数决定了空间的大小比例。
  • addItem(item):添加一个布局项到布局中。
  • setSpacing(spacing):设置控件之间的间距。
  • setContentsMargins(left, top, right, bottom):设置布局的外边距。
  • removeWidget(widget):从布局中移除一个控件。
  • count():返回布局中控件的数量。
  • itemAt(index):返回指定索引处的布局项。

示例:

python
import sys
from PyQt6.QtWidgets import QApplication, QPushButton, QLabel, QVBoxLayout, QHBoxLayout, QWidget, QMainWindow

app = QApplication([])

# 创建主窗口
window = QMainWindow()

# 创建中心部件,并设置为主窗口的中心部件
central_widget = QWidget()
window.setCentralWidget(central_widget)

# 创建按钮
button1 = QPushButton("按钮 1")
button2 = QPushButton("按钮 2")
button3 = QPushButton("按钮 3")

# 创建水平布局
h_layout = QHBoxLayout()
h_layout.addWidget(button1)
h_layout.addWidget(button2)

# 创建垂直布局
v_layout = QVBoxLayout()
v_layout.addLayout(h_layout)  # 添加水平布局
v_layout.addWidget(button3)
v_layout.addWidget(QLabel("这是底部标签"))

# 设置中心部件的布局
central_widget.setLayout(v_layout)

# 显示窗口
window.show()

# 运行应用程序
sys.exit(app.exec())

设计师软件可以很方便地管理布局。在设计师软件中,选中已经预先排列好的控件,右击其中一个,然后在弹出的菜单中选择布局、选择你要的布局。

更多控件在这里不再演示。实际开发中,除文档中列出的控件外,还可以使用用于展示表格的QTableWidget、展示画布,可显示 MatPlotLib 图像的 QGraphicsView 等控件。

为方便开发而创建的常用库指南