信号与槽-高级应用
1. 高级自定义信号与槽
自定义信号的一般流程:
1)定义信号
2)定义槽函数
3)连接信号与槽函数
4)发射信号
实例
import sys from PyQt5.QtCore import pyqtSignal, QObject class CustSignal(QObject): # 声明无参数的信号 signal1 = pyqtSignal() # 声明带一个int类型参数的信号 signal2 = pyqtSignal(int) # 声明带int和str类型参数的信号 signal3 = pyqtSignal(int, str) # 声明带一个列表类型参数的信号 signal4 = pyqtSignal(list) # 声明带一个字典类型参数的信号 signal5 = pyqtSignal(dict) # 声明带一个多重载版本的信号,包括带int和str类型参数的信号和带str类型参数的信号 signal6 = pyqtSignal([int, str], [str]) def __init__(self, parent=None): super().__init__(parent) # 将信号连接到指定槽函数 self.signal1.connect(self.signalCall1) self.signal2.connect(self.signalCall2) self.signal3.connect(self.signalCall3) self.signal4.connect(self.signalCall4) self.signal5.connect(self.signalCall5) self.signal6[int, str].connect(self.signalCall6) self.signal6[str].connect(self.signalCall6OverLoad) # 发射信号 self.signal1.emit() self.signal2.emit(1) self.signal3.emit(1, "text") self.signal4.emit([1, 2, 3, 4]) self.signal5.emit({"name": "wangwu", "age": 14}) self.signal6[int, str].emit(1, "text") self.signal6[str].emit("text") def signalCall1(self): print("signal1 emit") def signalCall2(self, val): print("signal2 emit, value:", val) def signalCall3(self, val, text): print("signal3 emit, value:", val, text) def signalCall4(self, val): print("signal4 emit, value:", val) def signalCall5(self, val): print("signal5 emit, value:", val) def signalCall6(self, val, text): print("signal6 emit, value:", val, text) def signalCall6OverLoad(self, val): print("signal6 overload emit, value:", val) if __name__ == "__main__": custSignal = CustSignal()
2. 使用自定义参数
解决信号发出的参数个数小于槽函数接收的参数个数的两种方法,重点是自定义参数的传递:
1. 使用 lambda 表达式。
import sys from PyQt5.QtWidgets import QMainWindow, QWidget, QApplication, QPushButton, QMessageBox, QHBoxLayoutclass WinForm(QMainWindow): def __init__(self, parent=None): super().__init__(parent) btn1 = QPushButton("Button 1") btn2 = QPushButton("Button 2") btn1.clicked.connect(lambda: self.onButtonClick(1)) btn2.clicked.connect(lambda: self.onButtonClick(2)) layout = QHBoxLayout() layout.addWidget(btn1) layout.addWidget(btn2) main_form = QWidget() main_form.setLayout(layout) self.setCentralWidget(main_form) def onButtonClick(self, n): print("Button {0} 被按下了".format(n)) QMessageBox.information(self, "信息提示框", "Button {0} clicked".format(n)) if __name__ == "__main__": app = QApplication(sys.argv) win = WinForm() win.show() sys.exit(app.exec_())
2. 使用functools 中的 partial 函数。
import sys from PyQt5.QtWidgets import QMainWindow, QWidget, QApplication, QPushButton, QMessageBox, QHBoxLayout from functools import partial class WinForm(QMainWindow): def __init__(self, parent=None): super().__init__(parent) btn1 = QPushButton("Button 1") btn2 = QPushButton("Button 2") btn1.clicked.connect(partial(self.onButtonClick, 1)) btn2.clicked.connect(partial(self.onButtonClick, 2)) layout = QHBoxLayout() layout.addWidget(btn1) layout.addWidget(btn2) main_form = QWidget() main_form.setLayout(layout) self.setCentralWidget(main_form) def onButtonClick(self, n): print("Button {0} 被按下了".format(n)) QMessageBox.information(self, "信息提示框", "Button {0} clicked".format(n)) if __name__ == "__main__": app = QApplication(sys.argv) win = WinForm() win.show() sys.exit(app.exec_())