Python 中的 PyQt 库2025 年 1 月 11 日 | 阅读 25 分钟 尽管移动和 Web 应用程序似乎占据了软件开发市场,但对传统图形用户界面 (GUI) 桌面应用程序的需求仍然存在。对于热衷于使用 Python 编程语言创建这些类型应用程序的开发人员来说,有大量的库可供选择,包括 Tkinter、PyQt、wxPython、PySide2 等。在下面的教程中,我们将了解如何使用 Python 编程语言和 PyQt 开发 GUI 桌面应用程序。 理解 Python 中的 PyQt 库PyQt 是一个图形用户界面小部件工具包。它作为 Qt 的 Python 接口,Qt 是最著名和最流行的跨平台 GUI 库之一。PyQt 库由 RiverBank Computing Ltd. 开发。我们可以从其官方网站 https://riverbankcomputing.com/software/pyqt/download 下载最新版本的 PyQt。 PyQt 库有两种版本
尽管 PyQt4 可以基于 Qt 5.x 构建,但只支持与 Qt 4.x 兼容的一小部分。此声明意味着,如果我们决定使用 PyQt4,我们可能会错过 PyQt5 库中的一些新功能和改进。有关此主题的更多信息,也可以参考 PyQt4 的官方文档 - https://www.riverbankcomputing.com/static/Docs/PyQt4/qt_v5.html。 在下面的教程中,我们将介绍 PyQt5 库,因为它似乎是该库的未来。从现在开始,任何提及 PyQt 都将指代 PyQt5。 PyQt5 基于 Qt 5 版本,包含涵盖图形用户界面以及网络通信、线程、多媒体、XML 处理、正则表达式、SQL 数据库、多媒体、Web 浏览和 Qt 中可用的其他技术的类。PyQt5 库是一个顶层 Python 包,可以在一组 Python 模块中实现这些 Qt 类中的一千多个。 PyQt5 库与许多操作系统兼容,例如 Windows、Unix、Linux、macOS、Android 和 iOS。如果我们正在寻找一个库或框架来开发可以在多个平台上运行且在每个平台上都具有原生外观和感觉的应用程序,这可能是一个有吸引力的功能。 PyQt5 库有两种许可证可供选择
如果我们想使用 PyQt5 创建商业应用程序,那么我们将需要一个商业许可证进行安装。PyQt5 许可证必须与我们正在使用的 Qt 许可证兼容。如果使用 GPL 版本,代码还必须使用 GPL 兼容的许可证。 如何安装 PyQt 库?在系统或开发环境中安装 PyQt 时,我们有多种选择。第一种选择是从源代码构建。这可能有点复杂,所以我们可能希望避免它。如果想从源代码构建,可以参考该库的官方文档。 另一个选项是使用二进制 Wheel。Wheel 是一种非常流行的 Python 包安装管理方式。但是,我们必须注意,PyQt5 的 Wheel 仅适用于 Python 3.5 及更高版本。有适用于不同操作系统的 Wheel,例如:
这些 Wheel 包含后续 Qt 库的副本;因此,我们无需单独安装它们。 第三种选择是在 Linux 发行版和 macOS 上使用包管理器。对于 Windows,我们可以使用二进制 .exe 文件。第四种也是最后一种选择是使用 Anaconda 发行版在系统上安装 PyQt 库。让我们考虑下一节,我们选择了上述选项之一来安装 PyQt5。 使用 pip 安装 PyQt5为了安装 Python 模块,我们需要 'pip',这是一个管理安装来自受信任公共存储库的模块所需的包的框架。一旦我们有了 'pip',我们就可以使用 Windows 命令提示符 (CMD) 或终端中的命令安装 pyqt5 模块,如下所示: 语法 验证安装模块安装完成后,我们可以通过创建一个空的 Python 程序文件并写入如下 import 语句来验证它: 文件:verify.py 现在,保存上述文件并在终端中使用以下命令执行它: 语法 如果上述 Python 程序文件未返回任何错误,则模块已正确安装。但是,如果引发异常,请尝试重新安装模块,并且还建议参考模块的官方文档。 现在让我们创建第一个 PyQt 应用程序 创建第一个 PyQt 应用程序由于我们已成功安装 PyQt 库,让我们开始编写代码。我们将使用 Python 和 PyQt 创建一个 “Hello, World!” 应用程序。让我们考虑一些我们将遵循的步骤: 步骤 1: 从 PyQt5.QtWidgets 导入 QApplication 和所有所需的小部件。 步骤 2: 创建 QApplication 对象。 步骤 3: 创建应用程序 GUI 的对象。 步骤 4: 显示应用程序的 GUI。 步骤 5: 执行应用程序的事件循环(或主循环)。 我们将首先在当前工作目录中创建 Python 项目文件 intro.py 并导入所需的小部件。 以下代码片段演示了相同的内容: 文件:intro.py 说明 在上面的代码片段中,我们导入了 sys 库,它将允许我们管理应用程序的退出状态。我们还从 PyQt5 库的 QtWidgets 模块中导入了 QApplication、QLabel 和 QWidget 等类和小部件。 现在我们将创建 QApplication 类的一个对象。让我们考虑以下演示相同内容的代码片段: 文件:intro.py 说明 在上面的代码片段中,我们实例化了 QApplication 类。由于 QApplication 对象 (myApp) 进行了大量的初始化,我们应该在创建任何其他与 GUI 相关的对象之前创建它。QApplication 类的对象还处理通用命令行参数,因此在创建 myApp 时,我们还需要将 sys.argv 作为参数传入。 注意:sys.argv 包含传递给 Python 脚本的命令行参数列表。如果应用程序不接受命令行参数,我们可以使用空列表而不是 sys.argv。我们可以执行类似 myApp = QApplication([]) 的操作。第三步包括为应用程序创建 GUI。对于此示例,我们的 GUI 将基于 QWidget,它是 PyQt 中所有用户界面对象的基本类。让我们考虑以下代码片段,它演示了 GUI 的创建: 文件:intro.py 说明 在上面的代码片段中,我们创建了一个 QWidget 实例,它提供了创建应用程序窗口(或表单)所需的所有功能。在 setWindowTitle() 函数的帮助下,我们为窗口添加了标题。 然后我们使用 setGeometry() 函数来定义窗口的大小以及在屏幕上的位置。前两个参数是窗口在屏幕上放置的 x- 和 y-坐标。第三和第四个参数是窗口的宽度和高度。 每个实用的 GUI 应用程序都需要小部件!在这里,我们使用了一个 QLabel 对象 (firstMsg) 来在应用程序窗口上显示消息。QLabel 对象可以接受 HTML 文本,因此我们使用了 HTML 元素 ' 注意:在 PyQt5 中,我们可以使用任何小部件(QWidget 的子类)作为顶层窗口,甚至是按钮或标签。唯一的条件是不要向其传递父级。当我们这样使用小部件时,PyQt5 会自动为其提供标题栏并将其转换为普通窗口。父子关系用于两个互补的目的:
这种关系也定义了所有权,父级拥有其子级。PyQt5 所有权模型确保如果我们删除父级(例如,顶层窗口),它的所有子级(小部件)都会自动移除。 我们应该确保除了顶级窗口之外的任何 QWidget 对象都有一个父级,以避免内存泄漏。 现在我们已经完成了第三步,让我们编写最后两个步骤,并让第一个 PyQt GUI 应用程序准备就绪 文件:intro.py 说明 在上面的代码片段中,我们在 myWindow 上调用了 show() 函数。对 show() 函数的调用会调度一个绘制事件。换句话说,它在应用程序的事件队列中插入一个新事件。我们将在后面的部分中介绍事件循环。 注意:绘制事件是绘制构成 GUI 的小部件的请求。最后,我们通过调用 myApp.exec_() 函数启动了应用程序的事件循环。对 exec_() 函数的调用被封装在对 sys.exit() 的调用中,这允许我们在应用程序终止时干净地退出 Python 并释放内存资源。我们可以使用以下命令运行 intro.py: 命令 输出 ![]() 说明 在上面的输出中,应用程序显示一个带有其消息的窗口(基于 QWidget)。我们使用一个包含 HTML 格式消息的 QLabel 来显示消息。 理解 PyQt 的基础知识为了有效地使用 PyQt 库进行 GUI 应用程序开发,我们需要掌握 PyQt 逻辑的基本概念。其中一些概念包括:
这些元素将被视为 PyQt GUI 应用程序的构建块。它们中的大多数都表示为 Python 类。PyQt 库的 QtWidgets 模块提供了所有这些类。这些元素非常重要,因此我们将在下一节中介绍它们。 理解小部件QWidget 是所有用户界面对象或小部件的基类。这些是矩形图形组件,我们可以将它们放置在应用程序的窗口上以构建 GUI。小部件包含允许我们建模其外观和行为的属性和方法。它们还可以在屏幕上绘制自己的表示。 小部件还接收来自用户、窗口系统和许多其他来源的鼠标点击、按键和其他事件。每当小部件捕获一个事件时,它都会发出一个信号以宣布其状态更改。PyQt5 拥有丰富而现代的小部件集合,可用于不同的目的。一些最常见和有用的小部件如下:
现在让我们简要了解这些小部件的用法。 按钮 我们可以通过实例化 QPushButton 来创建按钮,这是一个提供经典命令按钮的类。一些典型的按钮有 OK、Apply、Cancel、Yes、No 和 Close。 这样的按钮也许是任何图形用户界面中最常用的小部件。每当我们点击它们时,我们都可以命令计算机执行操作。我们甚至可以响应用户点击按钮来执行活动。 标签 我们可以通过实例化 QLabel 来创建标签。标签为我们提供了一种以文本或图像形式显示有用信息的方法。 像这样的标签可以更好地说明 GUI 的目的或用法。我们可以通过不同的方式调整它们的外观,它们甚至可以接受 HTML 文本,正如我们之前看到的。我们还可以使用标签为另一个小部件指定焦点助记键。 单行文本编辑 行编辑是另一个常见的小部件,一个可以使用 QLineEdit 创建的单行文本框。当要求用户以纯文本格式插入或编辑数据时,行编辑很有用。 像这样的行编辑提供了基本的编辑操作,例如复制、粘贴、撤消、重做、拖放等等。 组合框 组合框是另一个有用的小部件,我们可以使用 QComboBox 创建它。组合框有助于以最小化屏幕空间的方式向用户呈现选项列表。 这些组合框由像素图、字符串或两者组成。组合框可以是只读的或可编辑的。只读组合框允许用户选择不同的选项之一,但不能添加自己的选项。但是,可编辑组合框允许用户添加新选项。 单选按钮 我们将在这里介绍的最后一个小部件是单选按钮,我们可以使用 QRadioButton 创建它。当需要用户从多个选项中选择一个时,单选按钮很有用。QRadioButton 对象是一个选项按钮,可以打开(选中)或关闭(未选中)。 PyQt5 拥有大量的小部件。在撰写本文时,有四十多个可供我们使用以创建应用程序的图形用户界面。我们上面介绍的小部件只是一个很小的样本;但是,它们向我们展示了 PyQt5 库的强大功能和灵活性。在下一节中,我们将介绍如何布局不同的小部件以创建现代且功能强大的应用程序 GUI。 理解布局管理器现在我们了解了小部件的含义及其在构建 GUI 中的用途。但是,我们如何排列一组小部件以创建连贯且功能强大的 GUI 呢?我们可以使用多种技术在表单或窗口上布局小部件。例如,我们可以使用 resize() 和 move() 函数进行绝对大小和位置。但是,这可能有一些缺点:
我们还可以使用 resizeEvent() 作为替代方案来动态计算小部件的大小和位置。但是,最有效的替代方案可能是使用布局管理器,这将提高代码的生产力并改善可维护性。 布局管理器是使我们能够将小部件放置在应用程序表单上我们希望它们所在位置的类。布局管理器会自动适应大小调整事件和内容更改。它们还控制其内部小部件的大小。这意味着当表单调整大小时,布局中的小部件会自动调整大小。 注意:如果您开发国际应用程序,您可能已经注意到翻译后的标签是如何被截断的。当目标语言比原始语言更冗长时,这种情况尤其可能发生。然而,这种能力可能有点棘手,有时在特别冗长的语言中会失败。布局管理器有助于避免这种常见陷阱。PyQt 提供了四个基本的布局管理器类
第一个布局管理器类是 QHBoxLayout,它允许我们从左到右水平排列小部件。 ![]() 小部件将一个接一个地出现,从左边开始。 让我们考虑以下代码片段,演示了 QHBoxLayout 类用于水平排列按钮。 示例 输出 ![]() 说明 在上面的代码片段中,我们导入了所需的模块。然后我们实例化了 QApplication 类并创建了一个窗口。然后我们为窗口设置了标题并实例化了 QHBoxLayout 类。我们向布局添加了一些小部件,并使用 setLayout() 函数在应用程序窗口中设置了水平布局。最后,我们使用 show() 函数显示窗口,并使用 sys.exit(myApp.exec_()) 函数退出应用程序的执行。 在上面的输出中,我们以水平排列方式添加了三个按钮。请注意,按钮以与我们在代码中添加它们的相同顺序从左到右显示。 下一个布局管理器类是 QVBoxLayout,它允许我们从上到下垂直排列小部件 ![]() 每个新小部件将出现在前一个小部件的下方。我们可以使用此类来构建垂直框布局的对象,并从上到下组织小部件。 让我们考虑以下代码片段,演示了 QVBoxLayout 类的用法: 示例 输出 ![]() 说明 在上面的代码片段中,我们导入了所需的模块。然后我们实例化了 QApplication 类并创建了一个窗口。然后我们为窗口设置了标题并实例化了 QVBoxLayout 类。我们向布局添加了一些小部件,并使用 setLayout() 函数在应用程序窗口中设置了垂直布局。最后,我们使用 show() 函数显示窗口,并使用 sys.exit(myApp.exec_()) 函数退出应用程序的执行。 在上面的输出中,我们以垂直排列方式添加了三个按钮。请注意,按钮以与我们在代码中添加它们的相同顺序从上到下显示。 第三个布局管理器类是 QGridLayout,它允许我们将小部件排列成行和列的网格。每个小部件在网格上都有一个相对位置。我们可以通过向小部件传递一对坐标 (row, column) 来定义小部件的位置。这些坐标应该是有效的 int 数字。它们定义了我们要将小部件放置在网格的哪个单元格。网格布局的工作方式如下: QGridLayout 占用其父级可用的空间,将其划分为行和列,并将每个小部件放置在其单元格中。 ![]() 现在让我们考虑以下代码片段,它演示了在 GUI 中使用 QGridLayout: 示例 输出 ![]() 说明 在上面的代码片段中,我们导入了所需的模块。然后我们实例化了 QApplication 类并创建了一个窗口。然后我们为窗口设置了标题并实例化了 QGridLayout 类。我们使用 addWidget() 函数向布局添加了一些小部件。请注意,在上述情况下,我们传递给此函数的第二个和第三个参数是定义每个小部件位置的整数参数。 在第 29 行和第 31 行,我们向 addWidget() 函数添加了另外两个参数。这些参数被称为 rowSpan 和 columnSpan,它们是传递给函数的第四个和第五个参数。我们可以利用它们使小部件占据多行或多列,就像我们在这里对 QPushButton('Button (2, 1) + Columns Span') 所做的那样。 然后我们使用 setLayout() 函数在应用程序窗口中设置网格布局。最后,我们使用 show() 函数显示窗口,并使用 sys.exit(myApp.exec_()) 函数退出应用程序的执行。 上述输出显示小部件排列在行和列的网格中。两个小部件还占据了多个单元格。 最后一个布局管理器类是 QFormLayout,它将小部件排列成两列布局。第一列通常在标签中显示消息。第二列通常包含 QLineEdit、QComboBox、QSpinBox 等小部件。这些小部件允许用户输入或编辑与第一列中的信息相关的数据。下图显示了表单布局在实践中的工作方式: ![]() 左栏包含标签,右栏包含字段小部件。如果处理数据库应用程序,这种布局类型在创建表单时可以显著提高生产力。 让我们考虑以下代码片段,它演示了使用 QFormLayout 对象来安排应用程序中的小部件。 示例 输出 ![]() 说明 在上面的代码片段中,我们导入了所需的模块。然后我们实例化了 QApplication 类并创建了一个窗口。然后我们为窗口设置了标题并实例化了 QFormLayout 类。我们注意到 QFormLayout 有一个方便的方法,称为 addRow()。我们可以使用此方法向布局添加一个包含两个小部件的行。addRow() 的第一个参数应该是一个标签,第二个参数应该是任何其他允许用户输入或编辑数据的小部件。 上述输出显示了一个使用表单布局的 GUI。第一列包含要求用户提供一些信息的标签。第二列显示允许用户输入或编辑我们要求他们提供的信息的小部件。 理解对话框我们可以使用 PyQt 开发两种类型的 GUI 桌面应用程序。根据我们用于创建主表单或窗口的类,我们将拥有以下之一:
我们将首先从对话框样式应用程序开始。在下一节中,我们将介绍主窗口样式应用程序。 我们需要创建一个继承自 QDialog 的 GUI 类,它是所有对话框窗口的基类,以便开发对话框样式应用程序。对话框窗口始终是一个顶级窗口,我们可以将其用作对话框样式应用程序的主窗口。 注意:对话框窗口通常也用于主窗口样式应用程序,用于与用户进行简短的通信和交互。当对话框窗口用于与用户通信时,它们可以是:
对话框窗口还可以提供返回值并具有默认按钮(OK 和 Cancel)。 对话框通常是顶级小部件。如果它有一个父级,它的默认位置将以父级的顶级小部件为中心。这种对话框也将共享父级的任务栏条目。如果我们没有为给定的对话框设置父级,那么该对话框将在系统任务栏中获得其条目。 让我们考虑以下代码片段,演示了使用 QDialog 开发对话框样式应用程序: 示例 输出 ![]() 说明 在上面的代码片段中,我们导入了所需的模块并为 GUI 定义了一个继承自 QDialog 的类。然后我们将 QVBoxLayout 对象赋值给 dialog_layout,将 QVFormLayout 对象赋值给 form_layout。然后我们将小部件添加到 form_layout 中。之后我们使用 dialog_layout 在表单上排列这些小部件。然后我们向应用程序添加了两个标准按钮。最后,我们将样板代码封装在 if __name__ == '__main__': 惯用法中。这被认为是 Pythonista 的最佳实践。 注意:如果我们观察上面代码块中的第 27 行,那么我们会注意到布局管理器可以相互嵌套。我们可以通过在容器布局上调用 addLayout() 函数并将嵌套布局作为参数传递给此方法来嵌套布局。理解主窗口大多数情况下,GUI 应用程序将是主窗口样式。这意味着这些应用程序由菜单栏、一些工具栏、状态栏和作为图形用户界面主要元素的中心小部件组成。应用程序具有多个对话框窗口以完成依赖于用户输入的次要操作也很常见。 我们将使用 QMainWindow 类来开发主窗口样式应用程序。QMainWindow 提供了一个框架,允许我们构建应用程序的 GUI。我们必须继承自 QMainWindow 来创建主 GUI 类。派生自 QMainWindow 的类的对象被视为主窗口。该类具有其内置布局,我们可以利用它来放置以下内容:
我们不能在未首先设置中心小部件的情况下创建主窗口。我们只需要一个中心小部件,即使它只是一个占位符。在这种情况下,我们可以使用 QWidget 对象作为中心小部件。我们可以使用 setCentralWidget() 函数设置主窗口的中心小部件。主窗口的布局将允许我们只有一个中心小部件;但是,它可以是单个小部件或复合小部件。 让我们考虑以下代码片段,它演示了在创建主窗口样式应用程序时使用 QMainWindow: 示例 输出 ![]() 说明 在上面的代码片段中,我们导入了所需的模块并定义了一个名为 myWindow 的类,它继承自 QMainWindow。然后我们初始化了一些函数并设置了窗口的标题。然后我们设置了一个 QLabel 作为中心小部件。然后我们调用了以下私有方法来创建 GUI 的不同元素。之后,我们创建了用于创建主菜单、工具栏和状态栏的方法。最后,我们实例化了类并执行了应用程序。 注意:每当我们在方法中实现 GUI 的不同组件时,我们都会使代码更具可读性和更易于管理。但是,这不是必需的,因此您可以自由地以您喜欢的方式组织代码。我们可以观察到主窗口样式应用程序的组件如下所示:
到目前为止,我们已经介绍了 PyQt5 小部件集中一些更重要的图形组件。在接下来的两节中,我们将介绍与 PyQt GUI 应用程序相关的其他一些重要概念。 理解应用程序在开发 PyQt GUI 应用程序时,我们将使用的最基本的类是 QApplication。此类是任何 PyQt 应用程序的核心。它管理应用程序的控制流及其主要设置。在 PyQt 中,任何 QApplication 对象都是一个应用程序。每个 PyQt GUI 应用程序都必须有一个 QApplication 对象。应用程序的一些职责包括:
从 QApplication 的上述核心职责中,我们可以得出结论,这是一个有助于开发 PyQt GUI 应用程序的基本类。 QApplication 最重要的职责之一是提供事件循环和完整的事件处理机制。现在让我们仔细看看事件循环。 理解事件循环GUI 应用程序是事件驱动的。此声明意味着方法和函数是根据用户操作执行的。例如,单击按钮、从组合框中选择元素、在文本编辑器中插入和更新文本、按下键盘上的键等等。这些用户操作通常称为事件。 事件通常由事件循环(也称为主循环)处理。事件循环是一个无限循环,其中处理和分发来自用户、窗口系统和任何其他来源的所有事件。事件循环等待事件发生,然后分发它以执行一些任务。事件循环持续工作,直到应用程序终止。 所有 GUI 应用程序都使用事件循环。事件循环是一个无限循环,它等待事件的发生。假设一个事件发生,那么循环会检查该事件是否是终止事件。如果是,则循环终止,应用程序退出。否则,事件被发送到应用程序的事件队列进行进一步处理,循环重新开始。 在 PyQt 中,我们可以通过在 QApplication 对象上调用 exec_() 函数来执行应用程序的事件循环。 要使事件触发响应动作,我们必须将事件与我们希望执行的动作连接起来。在 PyQt5 中,我们可以借助信号和槽机制建立这种连接。 信号与槽PyQt 库的小部件充当事件捕获器。此声明意味着每个小部件都可以捕获特定数量的事件,例如鼠标点击、按键等等。为了响应这些事件,小部件总是发出一个信号,一种宣布其状态改变的消息。 信号本身不执行任何任务。如果我们要让信号触发一个动作,我们必须将其连接到槽。这是在连接信号发出时执行动作的方法或函数。我们可以使用任何 Python 可调用对象(或回调)作为槽。 如果信号连接到槽,则每当信号发出时,槽都会被调用。如果信号未连接到任何槽,则不发生任何事情,信号将被忽略。以下是此机制的一些最支持的功能:
我们可以使用以下语法将信号连接到槽: 语法 每当发出信号时,都会调用 slot_func()。这将 slot_func 连接到 widget.signal 函数。 让我们考虑以下代码片段,演示了相同的内容: 示例 输出 ![]() 说明 在上面的代码片段中,我们导入了所需的模块并定义了槽函数。我们创建了 QApplication 类的对象并初始化了按钮。然后我们添加了小部件并设置了布局。最后,我们显示了窗口。此外,我们可以观察到按钮触发了连接 greetings() 函数的动作。 信号和槽机制是我们将用来为 PyQt5 GUI 应用程序注入活力的机制。这种机制将允许我们将用户事件转化为具体动作。 |
我们请求您订阅我们的新闻通讯以获取最新更新。