【QT】信号与槽
创始人
2024-04-30 14:34:43
0

信号与槽

信号(Signal)槽(Slot) 是Qt中对象之间的通信方式,可以用一个简单的栗子说明:当我们想要开灯时,按下开关发出指令,这就是信号;而灯泡接收到电流变化,发出光亮,这就是响应(槽)。

我们也可以换个称呼方式:

  • 信号:触发事件
  • 槽:响应函数

所有继承自QObject的类,都可以包含信号和槽。当对象的状态发生改变时,就会发出信号。当然,他并不关心是否有人接收到这个信号。

槽函数就是用来接收对象的一个方法或是接口,就跟信号发出去并不知道有没有槽接收一样,槽也不知道有没有信号来调动他,他只是个固有属性。

信号和槽之间的关系是开放多元的,你可以看见一个信号连接到好几个槽,也可以见到一个槽上有好几个信号。更诡异的是,甚至可以将一个信号插到另一个信号上。

Qt小组件有许多预定义的信号和槽,例如QAbstractButton有一个Clicked()的信号,QLineEdit有一个clear()的槽。一般通过信号的connect()方法,将信号与槽联系起来。例如:

button=QToolButton()
line_edit=QLineEdit()
button.clicked.connect(line_edit.clear)

connect()将会翻译一个QMetaObject对象,该对象可以与disconnect()方法使用,以断开连接。

当然,除了预设的函数外,信号也可以连接到自由函数:

import sys
from PySide6.QtWidgets import QApplication,QPushButtondef function():print("The 'function' has been called")app=QApplication()
button=QPushButton("Call function")
button.clicked.connect(function)
button.show()
sys.exit(app.exec())

信号类

信号类需要是QtCore.Signal()类的变量,一般我们定义信号,是在类方法的上面进行:

class Button(QWidget):clicked=Signal(Qt.MouseButton)

然后,我们就可以设置信号的发出:emit

def mousePressEvent(self.event):self.clicked.emit(event.button())

完整代码如下,这个Button将返回按下的鼠标按键类型。

class Button(QWidget):clicked=Signal(Qt.MouseButton)def __init__(self):super(Button, self).__init__()# 绑定信号与槽self.clicked.connect(self.PrintE)@Slot()def PrintE(self,arg):print(arg)def mousePressEvent(self,event):# 鼠标移动时,作为触发器发出信号self.clicked.emit(event.button())App=QApplication()
button=Button()
button.show()
sys.exit(App.exec())

在这里插入图片描述

Signal的构造函数可以接收一个元组或者一个Python类型或是C类型的列表:

signal1 = Signal(int)  # Python types
signal2 = Signal(QUrl)  # Qt Types
signal3 = Signal(int, str, int)  # more than one type
signal4 = Signal((float,), (QDate,))  # optional types

除此之外,它还可以接收定义信号名称的命名参数名。如果没有传递任何信息,则新信号将与赋值给它的变量具有相同的名称。

# TODO
signal5 = Signal(int, name='rangeChanged')
# ...
rangeChanged.emit(...)

Signal还带有可选参数,比如sumResult=Signal(int,arguments=['sum'])


槽类

QObject派生类中的slot应该由装饰器@QtCore.Slot()表示。同样,要定义Signal,只需传递类似QtCore.Signal()类的类型。

@Slot(str)
def slot_function(self, s):...

Slot()也接受名称和结果关键字。result关键字定义了将返回的类型,可以是C或Python类型。name关键字的行为与Signal()中的相同。如果没有传递任何名称,则新插槽将具有与正在装饰的函数相同的名称。


重载信号与槽

我们举个简单的栗子,来使用信号与槽。

import sys
from PySide6.QtWidgets import QApplication,QPushButton
from PySide6.QtCore import QObject,Signal,Slotclass Communicate(QObject):# 创建两个新的信号,一个用于处理整数类型,一个处理字符串类型speak=Signal((int,),(str,))def __init__(self,parent=None):super(Communicate, self).__init__()# 将 信号1 连接到 槽函数self.speak[int].connect(self.say_something)# 将 信号2 连接到 槽函数self.speak[str].connect(self.say_something)# 定义一个新的槽函数,将会接收一个整形或者一个字符串# 并且打印他们的名字@Slot(int)@Slot(str)def say_something(self,arg):if isinstance(arg,int):print("This is a number: ",arg)elif isinstance(arg,str):print("This is a String: ",arg)if __name__ == '__main__':app=QApplication(sys.argv)someone=Communicate()# 发送带有不同参数的'speak'信号# 当然,如果想要发射`str`类型的信号,必须指定,否则是以默认`int`类型进行的someone.speak.emit(10)someone.speak[str].emit("Hello everybody")

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...