PySide(PyQT)的信号槽框架的一个demo练习
QT的信号槽机制是一种非常优秀高效的对象间通信的方式。当调用 signal.emit(*args) 时,PySide 会通知所有连接到该信号的槽函数,并将参数传递给这些槽函数。如果将信号作为出入接口,可以方便地在画面中不同的构件、画面之间以及与功能函数间传递数据,实现程序的模块化设计和前后端分离,也为程序的迁移复用打下了基础。
一个信号与槽的demo:
import sys
from PySide6.QtCore import QObject, Signal
from PySide6.QtWidgets import QApplication, QWidget
# 定义一个功能函数类
class Myfunction(QObject):
signal_obj = Signal(object) # 功能函数类的信号
def __init__(self):
super().__init__()
# 连接信号到槽函数
self.signal_slot() # 连接信号到槽函数
self.var_obj = None # 功能函数实体的变量
# 定义槽函数和信号连接
def signal_slot(self):
def slot(obj):
self.var_obj = obj
print(f"功能函数实体接收到了外部信号:{obj}")
self.signal_obj.connect(slot) # 连接信号到槽函数
# 定义一个窗口类
class MyWidget(QWidget):
signal_obj = Signal(object) # 窗口类的信号
def __init__(self):
super().__init__()
# 连接信号到槽函数
self.signal_slot() # 连接信号到槽函数
self.var_obj = 0 # 窗口实体的变量
# 定义槽函数和信号连接
def signal_slot(self):
def slot(obj):
print(f"窗口实体接收到了内部信号:{obj}")
self.signal_obj.connect(slot) # 连接信号到槽函数
# 重写鼠标按下事件
def mousePressEvent(self, event):
super().mousePressEvent(event)
self.var_obj += 1
self.signal_obj.emit(self.var_obj) # 发送信号
if __name__ == '__main__':
app = QApplication(sys.argv)
func = Myfunction() # 功能函数实体
widget = MyWidget() # 窗口实体
widget.show()
# 连接项目级的信号到槽函数
def signal_slot():
def slot(obj): # 项目级的槽函数
func.signal_obj.emit(obj) # 功能函数实体发送信号
widget.signal_obj.connect(slot) # 窗口实体的信号发射后,连接到项目级的槽函数
signal_slot()
sys.exit(app.exec())
在这个代码中,重新定义了窗口类的鼠标按下的事件,当鼠标按下时,窗口实体的信号发射,窗口实体的信号连接了一个其自身的内部槽函数和一个项目级的槽函数,在项目级的槽函数中,功能函数实体的信号将接收到的窗口实体的信号发射并由其自身的内部槽函数接收。这样就实现了不同的组件之间的信号传递,而且每个组件的代码中不会出现不属于其自身的任何元素,为程序的模块化和前后端分离打下基础。
运行截图:
进一步的,将功能函数实体的运算结果发回窗口实体:
import sys
from PySide6.QtCore import QObject, Signal
from PySide6.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout
# 定义一个功能函数类
class Myfunction(QObject):
signal_input = Signal(object) # 功能函数类的输入信号
signal_output = Signal(object) # 功能函数类的输出信号
def __init__(self):
super().__init__()
# 连接信号到槽函数
self.signal_slot() # 连接信号到槽函数
self.var_obj = None # 功能函数实体的变量
def signal_slot(self):
def slot1(obj):
print(f"功能函数实体接收到了外部信号:{obj}")
self.var_obj = obj * 10 # 功能函数实体对输入信号进行处理
self.signal_output.emit(self.var_obj) # 功能函数实体发送信号
self.signal_input.connect(slot1) # 连接信号到槽函数
# 定义一个窗口类
class MyWidget(QWidget):
signal_input = Signal(object) # 窗口类接收到的信号
signal_output = Signal(object) # 窗口类发出的信号
def __init__(self):
super().__init__()
# 连接信号到槽函数
self.signal_slot() # 连接信号到槽函数
self.var_obj = 0 # 窗口实体的变量
self.setupUi()
def setupUi(self):
self.label = QLabel("", self) # 窗口实体的标签
layout = QVBoxLayout(self)
layout.addWidget(self.label) # 窗口实体的标签
def signal_slot(self):
def slot(obj):
self.label.setText(f"窗口实体接收到了外部信号:{obj}")
self.signal_input.connect(slot) # 连接信号到槽函数
# 重写鼠标按下事件
def mousePressEvent(self, event):
super().mousePressEvent(event)
self.var_obj += 1
self.signal_output.emit(self.var_obj) # 发送信号
if __name__ == '__main__':
app = QApplication(sys.argv)
func = Myfunction() # 功能函数实体
widget = MyWidget() # 窗口实体
widget.show()
# 连接项目级的信号到槽函数
def signal_slot():
def slot1(obj): # 项目级的槽函数
func.signal_input.emit(obj) # 功能函数的输入信号发送
widget.signal_output.connect(slot1) # 窗口实体的输出信号发射后,连接到项目级的槽函数
def slot2(obj): # 项目级的槽函数
widget.signal_input.emit(obj) # 窗口实体的输入信号发送
func.signal_output.connect(slot2) # 功能函数实体的输出信号发射后,连接到项目级的槽函数
signal_slot()
sys.exit(app.exec())
实现了信号的处理和交互: