前情回顾
在上期教程中,我们向大家简单介绍下PyQt
的基础概念及安装方法,同时教给大家一些基础的PyQt
入门知识,包括相关的一些组件集合以及构建窗口的方法。

在本期课程中,我们将为大家介绍PyQt
中应用程序的相关概念,包括事件循环、信号以及槽位,以帮助大家更灵活的处理程序运行可能会出现的各种状况。
Applications|应用
在开发PyQt
的GUI
应用程序时,QApplication
是最基本的类。该类是任何PyQt
应用程序的核心组件。它管理应用程序的控制流以及它的主要设置。
在PyQt
中,QApplication
的任何实例都是一个应用程序。每个PyQt
GUI应用程序必须有一个
QApplication`实例。这个类的一些功能包括:
-
处理应用程序的初始化和结束 -
提供事件循环和事件处理 -
处理大多数系统范围和应用程序范围的设置 -
提供对全局信息的访问,例如应用程序的目录、屏幕大小等 -
解析常用的命令行参数 -
定义应用程序的外观 -
提供本地化功能
以上这些只是QApplication
的一些核心职责。因此,在开发PyQt GUI
应用程序时,这是一个基本类。QApplication
最重要的特性之一是提供事件循环和整个事件处理机制。在下一小节中,你将深入了解什么是事件循环以及它是如何工作的。
Event Loops|事件循环
GUI
应用程序是通过事件驱动的。这意味着函数和方法是根据用户操作调用的,比如单击按钮、从组合框中选择项、在文本编辑中输入或更新文本、按下键盘上的一个键等等。这些用户操作通常称为事件。
事件由事件循环处理,也称为主循环。事件循环是一个无限循环,在这个循环中,来自用户、窗口系统和任何其他源的所有事件都被处理和分派。事件循环等待事件发生,然后将其分派去执行某些任务。事件循环将继续工作,直到应用程序终止。
所有GUI
应用程序都有一个事件循环。当事件发生时,循环检查它是否为终止事件。在这种情况下,循环结束,应用程序退出。否则,事件将被发送到应用程序的事件队列进行进一步处理,并再次循环。在PyQt6
中,可以通过在QApplication
对象上调用.exec()
来运行应用程序的事件循环。
要使事件触发操作,你需要将事件与想要执行的操作连接起来。在PyQt
中,可以用信号和槽机制建立连接,这将在下一小节中进行探讨。
Signals and Slots|信号和槽位
PyQt
小部件充当事件捕获器。这意味着每个小部件都可以捕获特定的事件,如鼠标点击、按键等。作为对这些事件的响应,小部件发出一个信号,这是一种宣布其状态发生变化的消息。
信号本身不执行任何动作。如果你想要一个信号触发一个动作,那么你需要把它连接到一个插槽。这是一个函数或方法,它将在发出相关信号时执行操作。可以使用任何Python可调用对象作为插槽。
如果一个信号连接到一个槽位,那么每当信号发出时就调用该插槽。如果一个信号没有连接到任何槽,那么什么也不会发生,信号将被忽略。信号和槽的一些最相关的特性包括:
-
一个信号可以连接到一个或多个槽位。 -
一个信号也可以连接到另一个信号。 -
一个槽可以连接到一个或多个信号。
下面的代码将展示如何在PyQt
应用程序中使用信号和插槽机制:
# signals_slots.py
"""Signals and slots example."""
import sys
from PyQt6.QtWidgets import (
QApplication,
QLabel,
QPushButton,
QVBoxLayout,
QWidget,
)
def greet():
if msgLabel.text():
msgLabel.setText("")
else:
msgLabel.setText("Hello, World!")
app = QApplication([])
window = QWidget()
window.setWindowTitle("Signals and slots")
layout = QVBoxLayout()
button = QPushButton("Greet")
button.clicked.connect(greet)
layout.addWidget(button)
msgLabel = QLabel("")
layout.addWidget(msgLabel)
window.setLayout(layout)
window.show()
sys.exit(app.exec())
当我们尝试运行该脚本时,会弹出如下窗口:

当单击Greet
按钮时,Hello, World!
消息在应用程序的主窗口上出现和消失。
注意:每个小部件都有自己的一组预定义信号,大家可以在相应的文档中查看它们。
如果你的slot
函数需要接收额外的参数,那么你可以使用functools.partial()
传递它们。例如,你可以修改greet()
来接受一个参数,如下面的代码所示:
# signals_slots.py
# ...
def greet(name):
if msg.text():
msg.setText("")
else:
msg.setText(f"Hello, {name}")
# ...
现在greet()
需要接收一个名为name
的参数。如果你想把这个新版本的greet()
连接到.clicked
信号,你可以这样做:
# signals_slots.py
"""Signals and slots example."""
import sys
from functools import partial
# ...
button = QPushButton("Greet")
button.clicked.connect(partial(greeting, "World!"))
# ...
要使这段代码正常工作,你首先需要从functools
导入partial()
。对partial()
的调用返回一个函数对象,当使用name="World!"
调用时,该函数对象的行为与greet()
类似。现在,当用户单击按钮时,消息Hello, World!
会像以前一样出现在标签上。
注意:你还可以使用
lambda
函数将信号连接到需要额外参数的槽位。作为练习,大家可以尝试使用lambda
而不是functools.partial()
来编写上面的示例。
信号和槽机制将用于赋予PyQt GUI
应用程序生命。这种机制将允许我们将用户事件转换为具体的操作。相信大家已经了解了PyQt
的几个重要概念的基础知识。有了这些知识和库的文档,你就可以开始开发自己的GUI
应用程序了。在下一节中,我们将带大家构建第一个功能齐全的GUI
应用程序——桌面计算器。
【Python项目实战】网页爬取(上)
【Python项目实战】网页爬取(中)
【Python项目实战】网页爬取(下)
【Python项目实战】主流游戏引擎(上)
【Python项目实战】主流游戏引擎(中)
【Python项目实战】主流游戏引擎(下)
原文始发于微信公众号(Pytrick):【Python项目实战】构建GUI桌面计算器(中)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/56353.html