PyQt5信号槽机制(一)
信号槽是Qt的核心机制,也是PyQt中编程的通信机制,在Qt中,QObject对象和PyQt中所有继承自QWidget的控件都支持信号机制。当信号发射时,连接的槽函数会自动执行。在PyQt5中,信号和槽函数通过object.signal.connect()
方法进行连接。
信号槽(slot)简介
信号槽特点如下:
- 一个信号可以连接多个槽
- 一个信号可以连接另一个信号
- 信号参数可以是任意Python类型
- 一个槽可以监听任意多个信号
- 信号与槽之间的连接方式可以是同步连接,也可以是异步连接
- 信号与槽的连接可以跨线程
- 信号可以断开
在编写一个类的时候,要首先定义类的信号和槽,在类的信号与槽进行连接,实现对象之间的数据传输。当事件或状态发生改变时,会发出信号,进而出发执行事件或信号相关联的槽函数
定义信号
PyQt内置信号是自动定义的,使用PyQt5.QtCore.pyqtSignal
函数可以为QObject对象创建一个信号,使用pyqtSignal函数可以把信号定义为类的属性。pyqtSignal的原型如下
1 2
| class pyqtSignal: def __init__(self, *types, name: str= ...) -> None: ...
|
type
:表示定义信号时参数的类型
name
:表示信号的名称,默认使用类的属性名称
使用pyqtSignal
函数创建一个或多个重载的未绑定的信号作为类的属性,信号只能在QObject
的子类中定义。信号必须在类创建时定义,不能在类创建后作为类的属性动态添加进来。使用pyqtSignal函数定义信号时,信号可以传递多各参数,并指定信号传递参数的类型,参数类型是标准的Python数据类型,包括字符串、日期、布尔类型、数字、列表、字典、元组。
1 2 3 4 5 6 7 8
| from PyQt5.QtCore import pyqtSignal, QObject
class StandardItem(QObject): data_changed = pyqtSignal(str, str, name='dataChanged') def update(self): self.dataChanged.emit("old status","new status")
|
操作信号
connect
函数:将信号绑定到槽函数上,QObject.signal.connect(self, slot, type=None, no_receiver_check=False)
disconnect
函数:将信号解绑,QObject.signal.disconnect(self, slot=None)
emit
函数:发射信号,emit(self, *args)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| from PyQt5.QtCore import pyqtSignal, QObject
class StandardItem(QObject): data_changed = pyqtSignal(str, str, name='dataChanged')
def update(self): self.dataChanged.emit("old status","new status")
def onDataChanged(self, old, new): print(old) print(new)
if __name__ == '__main__': app = QCoreApplication(sys.argv) item = StandardItem() item.dataChanged.connect(item.onDataChanged) item.update()
sys.exit(app.exec_())
|
信号槽与应用
内置信号与自定义槽函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import sys from PyQt5.QtWidgets import QWidget, QApplication, QPushButton
class MainWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("MainWindow Demo") self.resize(800, 600)
button = QPushButton("close", self) button.clicked.connect(self.onClose)
def onClose(self): self.close()
if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show()
sys.exit(app.exec_())
|
这里,button.click()
就是一个内置信号,他与onClose槽函数连接。而用户按下的动作即为发射。点击按钮时触发按钮内置的clicked信号,执行绑定的自定义槽函数onClose。
自定义信号和内置槽函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import sys from PyQt5.QtCore import pyqtSignal from PyQt5.QtWidgets import QWidget, QApplication, QPushButton
class MainWindow(QWidget): closeSignal = pyqtSignal()
def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("MainWindow Demo") self.resize(800, 600)
button = QPushButton("close", self) button.clicked.connect(self.onClose) self.closeSignal.connect(self.close)
def onClose(self): self.closeSignal.emit()
if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show()
sys.exit(app.exec_())
|
通过内置信号click
连接到自定义槽函数,槽函数中触发自定义信号的发射,从而触发内置槽函数QWidget.close()
函数
自定义信号和自定义槽函数
结合上述两种方法,大同小异
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import sys from PyQt5.QtCore import pyqtSignal from PyQt5.QtWidgets import QWidget, QApplication, QPushButton
class MainWindow(QWidget): closeSignal = pyqtSignal()
def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("MainWindow Demo") self.resize(800, 600)
button = QPushButton("close", self) button.clicked.connect(self.onClicked) self.closeSignal.connect(self.onClose)
def onClicked(self): self.closeSignal.emit()
def onClose(self): self.close()
if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show()
sys.exit(app.exec_())
|
参考自:
PyQt5快速入门(二)PyQt5信号槽机制