在Qt中,控件与控件之间的联系全靠信号(Signals)与槽(Slots)来进行对接。例如一个清空按钮发送了点击的信号,输入框通过连接该按钮的点击信号,当收到点击信号时,进行清空输入框文本的操作,如此完成清空输入框内容的逻辑。
用一张图来说明信号与槽的关系:
比方说有一个看不见东西可怜的小明,他需要买肉做红烧肉,当他来到集市上,听到有猪肉荣的叫卖声时,就去买肉回家做红烧肉了。
如果小明想要买肉做红烧肉,同时他又想修仙,那么当他听到卖肉的叫卖声和卖仙丹的叫卖声,他就会到两个摊位上都买,然后可能用肉做红烧肉,仙丹直接吃;也有可能把肉和仙丹一起做成仙丹炒肉的名菜再吃。
所以一个槽函数可以接收多种信号,一个信号也可以发送给多个槽(相当于小明哥哥、小明妹妹、小明弟弟、包租婆、包租公、火云邪神等等都来买肉)。
比如说你有个自定义的槽函数test在主控件中,则只需要右键该主控件(根控件),选择改变 信号/槽即可:
在代码中添加槽函数,并在槽函数中实现相应逻辑:
class MyWindow(QMainWindow):
...
def test(self):
# 实现逻辑
pass
自定义信号也是如此操作。 关于槽函数中的参数,可以根据信号的传参类型填写。
首先,添加自定义信号的基类需要为QObject,否则将会报错:
# -*- coding: utf-8 -*-
from PySide6 import QtCore
class CustomWidget(QtCore.QObject):
sig_test_1 = QtCore.Signal()
sig_test_2 = QtCore.Signal(float)
sig_test_3 = QtCore.Signal(tuple)
sig_test_4 = QtCore.Signal(int, int)
def test_1(self):
self.sig_test_1.emit()
def test_2(self):
self.sig_test_2.emit(0.5)
def test_3(self):
self.sig_test_3.emit(('test', 20, [2, 3, 4, 5]))
def test_4(self):
self.sig_test_4.emit(20, 30)
一般来说,在开发Qt项目时,很多控件可能无法我们的满足,因此需要继承控件去扩展功能,此时经常会使用到自定义信号来完成功能。
def test(index):
pass
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
# currentIndexChanged为ComboBox的一个自带信号,会发送一个下标
self.unit_combo_box.currentIndexChanged.connect(self.unit_change)
self.unit_combo_box.currentIndexChanged.connect(test)
def unit_change(self, index):
pass
可以看到一个信号连接槽函数通过connect方法,可以是对象方法,也可以是一个单独的函数。
对应的,还有一个disconnect方法来解除连接,不过用到的情况不多。
点进控件的源码中,查看该部分内容:
如果类似pyqtgraph的库,信号也可以在类名下方找到:
为了连接各个控件,完成需求开发,信号与槽的应用不可避免,如何运用好内置信号与槽,如何定义好自定义信号和槽都是需要慢慢开发,积累经验的。