signal and solt 信号和卡槽
这个是pyside机制的核心,如果你理解不了这个,pyside是玩不转的,
信号和插槽#
由于Qt的性质,s需要一种通信方式,这就是这种机制成为Qt的核心特征的原因。QObject
简单来说,您可以像与房屋中的灯光互动一样理解信号和插槽。当您移动电灯开关(信号)时,您得到的结果可能是您的灯泡已打开/关闭(插槽)。
在开发接口时,您可以通过单击按钮的效果获得一个真实的例子:“单击”将是信号,而插槽将是单击该按钮时发生的情况,例如关闭窗口,保存文档等。
注意
如果您有使用其他框架或工具包的经验,那么您很可能会阅读一个名为“回调”的概念。撇开实现细节不谈,回调将与通知函数相关,传递指向函数的指针,以防由于程序中发生的事件而需要它。这种方法可能听起来很相似,但存在一些本质差异,使其成为一种不直观的方法,例如确保回调参数的类型正确性,以及其他一些方法。
所有继承自或其子类之一的类(如)都可以包含信号和槽。当对象以其他对象可能感兴趣的方式更改其状态时,它们会发出信号。这就是对象进行通信的全部内容。它不知道也不关心是否有任何东西正在接收它发出的信号。这是真正的信息封装,并确保对象可以用作软件组件。QObject
QWidget
插槽可用于接收信号,但它们也是普通的成员函数。就像一个物体不知道是否有任何东西接收到它的信号一样,一个插槽也不知道它是否有任何信号连接到它。这确保了可以使用Qt创建真正独立的组件。
您可以将任意数量的信号连接到单个插槽,并且信号可以根据需要连接到任意数量的插槽。甚至可以将一个信号直接连接到另一个信号。(每当发出第一个信号时,这将立即发出第二个信号。
Qt的小部件有许多预定义的信号和插槽。例如,QAb 字符串按钮(Qt 中按钮的基本类)具有单击 () 信号,而 QLine 编辑(单行输入字段)具有名为“清除()”的插槽。因此,可以通过在QLineEdit的右侧放置一个QTool按钮并将其单击()信号连接到插槽“clear()”来实现带有清除文本按钮的文本输入字段。这是使用信号的连接()方法完成的:
button = QToolButton() line_edit = QLineEdit() button.clicked.connect(line_edit.clear)
连接() 返回一个 QMeta 对象,该对象可与断开连接() 方法一起使用以断开连接。
信号也可以连接到自由功能:
import sys from PySide6.QtWidgets import QApplication, QPushButton def function(): print("The 'function' has been called!") app = QApplication() button = QPushButton("Call function") button.clicked.connect(func) button.show() sys.exit(app.exec())
连接可以在代码中拼写出来,或者对于小部件表单,可以在Qt Designer的信号槽编辑器中设计。
信号类
在 Python 中编写类时,信号被声明为类 的类级变量。发出单击()信号的基于QWidget的按钮可能如下所示:QtCore.Signal()
from PySide6.QtCore import Qt, Signal from PySide6.QtWidgets import QWidget class Button(QWidget): clicked = Signal(Qt.MouseButton) ... def mousePressEvent(self, event): self.clicked.emit(event.button())
的构造函数采用元组或 Python 类型和 C 类型的列表:Signal
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
除此之外,它还可以接收定义信号名称的命名参数。如果未传递任何内容,则新信号将与要分配到的变量具有相同的名称。name
# TODO signal5 = Signal(int, name='rangeChanged') # ... rangeChanged.emit(...)
另一个有用的选项是参数名称,对于 QML 应用程序按名称引用发出的值很有用:Signal
sumResult = Signal(int, arguments=['sum'])
Connections { target: ... function onSumResult(sum) { // do something with 'sum' }
派生类
Q对象派生类中的槽应由装饰器 指示。同样,要定义签名,只需传递与类类似的类型即可。@QtCore.Slot()
QtCore.Signal()
@Slot(str) def slot_function(self, s): ...
Slot()
也接受 和 关键字。关键字定义将返回的类型,可以是 C 或 Python 类型。关键字的行为方式与 中的行为方式相同。如果没有作为名称传递任何内容,则新槽将与正在修饰的函数具有相同的名称。name
result
result
name
Signal()
不同类型的过载信号和插槽
实际上,可以将同名的信号和槽用于不同的参数类型列表。这是Qt 5的遗留物,不建议用于新代码。在 Qt 6 中,信号对于不同类型的信号具有不同的名称。
以下示例对信号和槽使用两个处理程序来展示不同的功能。
import sys from PySide6.QtWidgets import QApplication, QPushButton from PySide6.QtCore import QObject, Signal, Slot class Communicate(QObject): # create two new signals on the fly: one will handle # int type, the other will handle strings speak = Signal((int,), (str,)) def __init__(self, parent=None): super().__init__(parent) self.speak[int].connect(self.say_something) self.speak[str].connect(self.say_something) # define a new slot that receives a C 'int' or a 'str' # and has 'say_something' as its name @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() # emit 'speak' signal with different arguments. # we have to specify the str as int is the default someone.speak.emit(10) someone.speak[str].emit("Hello everybody!")
按方法签名字符串指定信号和槽
信号和槽也可以指定为通过 SIGNAL() 和/或 SLOT() 函数传递C++方法签名字符串:
from PySide6.QtCore import SIGNAL, SLOT button.connect(SIGNAL("clicked(Qt::MouseButton)"), action_handler, SLOT("action1(Qt::MouseButton)"))
不建议将其用于连接信号,它主要用于指定 QWizardPage::寄存器字段()等方法的信号:
wizard.registerField("text", line_edit, "text", SIGNAL("textChanged(QString)"))
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了