- PyQt 教程
- PyQt - 首页
- PyQt - 简介
- PyQt - 环境配置
- PyQt - Hello World
- PyQt - 主要类
- PyQt - 使用Qt Designer
- PyQt - 元对象
- PyQt 信号与槽
- PyQt - 信号和槽
- PyQt - 支持和信号
- PyQt - 未绑定和已绑定信号
- PyQt - 使用PyQtSignal创建新的信号
- PyQt - 连接、断开和发射信号
- PyQt - 槽装饰器
- PyQt - 槽连接
- PyQt 布局
- PyQt - 布局管理
- PyQt - QBoxLayout
- PyQt - QGridLayout
- PyQt - QFormLayout
- PyQt - QHBoxLayout
- PyQt - QVBoxLayout
- PyQt - QStackedLayout
- PyQt - QGraphicsGridLayout
- PyQt - QGraphicsAnchorLayout
- PyQt - QGraphicsLayout
- PyQt - QGraphicsLinearLayout
- PyQt 基础部件
- PyQt - 基础部件
- PyQt - QLabel部件
- PyQt - QLineEdit部件
- PyQt - QPushButton部件
- PyQt - QRadioButton部件
- PyQt - QCheckBox部件
- PyQt - QComboBox部件
- PyQt - QSpinBox部件
- PyQt - QMessageBox
- PyQt - QDialogButtonBox部件
- PyQt - QFontComboBox部件
- PyQt - QDoubleSpinBox部件
- PyQt - QToolBox部件
- PyQt - QDialog类
- PyQt - QMessageBox
- PyQt - 多文档界面
- PyQt - 拖放操作
- PyQt 绘图API
- PyQt - 绘图API
- PyQt 数据库
- PyQt - 数据库处理
- PyQt 核心知识
- PyQt - BrushStyle 常量
- PyQt - QClipboard
- PyQt - QPixmap类
- PyQt 有用资源
- PyQt - 快速指南
- PyQt - 有用资源
- PyQt - 讨论
PyQt - 使用PyQtSignal创建新的信号
PyQt 自动为所有 Qt 内置信号定义信号,但有时需要自定义信号来简化应用程序不同部分之间的通信。这就是 **pyqtSignal** 帮助开发者使用 **PyQtSignal 工厂** 将新的自定义信号定义和创建为类属性的地方。
pyqtSignal 的语法和参数
我们可以使用 **pyqtSignal** 将新的信号定义为类属性,如下所示:
PyQt6.QtCore.pyqtSignal(types[, name[, revision=0[, arguments=[]]]])
在上面的语法中,传递给 pyqtSignals 的参数扮演着不同的角色,如下所示:
- **types** - 定义构成信号 C++ 签名的类型。每个类型可以是 Python 类型对象,表示 C++ 类型的字符串,或定义多个信号重载的类型参数序列。例如,int、float 等。
- **name(可选)** - 指定信号的名称。如果省略,则使用类属性的名称。
- **revision(可选)** - 指定导出到 QML(Qt 建模语言)的信号的修订版。
- **arguments(可选)** - 指定导出到 QML 的信号参数的名称。
定义新的信号
PyQt 中的新信号指定了当某些特定操作发生或某些状态发生变化时,由对象发出的事件或条件。当发出新信号时,连接到这些信号的对象可以执行相应的代码,从而实现应用程序不同部分之间有效的通信和交互。
信号定义示例
from PyQt6.QtCore import QObject, pyqtSignal class Foo(QObject): # Define a signal called 'closed' with no arguments. closed = pyqtSignal() # Define a signal called 'rangeChanged' with two integer arguments. range_changed = pyqtSignal(int, int, name='rangeChanged') # Define a signal called 'valueChanged' with two overloads: int and QString. valueChanged = pyqtSignal([int], ['QString'])
定义新信号的指南
- 新信号只能在 QObject 的子类中定义。
- 新信号必须是类定义的一部分,不能在类定义后动态添加。
- 使用 pyqtSignal 定义的新信号会自动添加到类的 QMetaObject 中,使其可在 Qt Designer 和通过 QMetaObject API 访问。
重载信号的注意事项
当我们定义重载信号时,即信号包含多个信号签名类型,在处理没有相应 C++ 类型的 Python 类型时,我们应该谨慎。可能存在具有不同 Python 签名但 C++ 签名相同的重载信号,这会导致意外行为。
具有意外行为的重载信号示例
class Foo(QObject): # This will cause problems because each has the same C++ signature. cautiousSignal = pyqtSignal([dict], [list])
PyQt 在内部会将 [dict] 和 [list] 都视为数组类型,从而导致信号的意外行为。
新的简单信号示例
在下面的示例中,我们定义了一个从 **QObject** 继承的 PyQt 类 **Counter**。我们定义了一个自定义新信号,当被调用时发出一个整数。increment 方法将内部 _value 属性增加 1 并使用更新的值发出 valueChanged 信号。创建 Counter 的实例,并将 lambda 函数连接到其 valueChanged 信号,以便在调用 increment 方法时打印当前值。
from PyQt6.QtCore import QObject, pyqtSignal class Counter(QObject): valueChanged = pyqtSignal(int) def __init__(self): super().__init__() self._value = 0 def increment(self): self._value += 1 self.valueChanged.emit(self._value) counter = Counter() counter.valueChanged.connect(lambda value: print(f"Counter value: {value}")) counter.increment()
输出
Counter value: 1
带有参数的自定义新信号示例
在这个例子中,我们定义了一个从 **QObject** 继承的 **Worker** 类。一个新的自定义信号 **job_done** 使用 **pyqtSignal** 定义,它发出一个字符串。
do_work 方法模拟工作并使用消息发出 job_done 信号。创建 Worker 的实例,并将 lambda 函数连接到其 job_done 信号,在任务完成后打印工作程序的状态。
from PyQt6.QtCore import QObject, pyqtSignal class Worker(QObject): job_done = pyqtSignal(str) def do_work(self): # Simulating some work result = "Task completed successfully" self.job_done.emit(result) worker = Worker() worker.job_done.connect(lambda message: print(f"Worker status: {message}")) worker.do_work()
输出
Worker status: Task completed successfully
重载新信号示例
在这个示例中,我们使用 **QVariant** 作为信号的类型参数,并将参数名称指定为 'data'。发出信号时,我们传递字典作为参数。
使用 **QVariant** 允许我们通过信号在 PyQt 对象之间传递像字典这样的复杂数据类型。
from PyQt6.QtCore import QObject, pyqtSignal, QVariant class Loader(QObject): data_loaded = pyqtSignal(QVariant, arguments=['data']) def load_data(self): # Simulating data loading data_dict = {"key1": "value1", "key2": "value2"} self.data_loaded.emit(data_dict) loader = Loader() loader.data_loaded.connect(lambda data: print(f"Data loaded: {data}")) loader.load_data()
输出
Data loaded: {'key1': 'value1', 'key2': 'value2'}