信号与槽基础
自定义信号实现对象之间的通信
可以传递多个参数的信号
为类添加多个信号
信号对槽的N对N连接和断开连接
为窗口添加信号
多线程更新UI数据
代码
from PyQt5.QtCore import QThread,pyqtSignal,QDateTimefrom PyQt5.QtWidgets import QApplication,QDialog,QLineEditimport timeimport sysclass BackendThread(QThread):update_date = pyqtSignal(str)def run(self):while True:data=QDateTime.currentDateTime()currentTime = data.toString('yyyy-MM-dd hh:mm:ss')self.update_date.emit(str(currentTime))time.sleep(1)passpasspassclass ThreadUpadteUI(QDialog):def __init__(self):QDialog.__init__(self)self.setWindowTitle('多线程更新UI数据')self.resize(400,100)self.input= QLineEdit(self)self.input.resize(400,100)self.initUI()passdef initUI(self):self.backend = BackendThread() # 定义线程self.backend.update_date.connect(self.handleDiaplay)self.backend.start()passdef handleDiaplay(self,data):self.input.setText(data)passpassif __name__ == '__main__': # 只有这个文件单独执行才会调用该语句app = QApplication(sys.argv) # 传入参数main = ThreadUpadteUI()main.show()sys.exit(app.exec_()) # 进入程序的主循环
结果

信号与槽自动连接
使用Lambda表达式为槽传递参数
概念
- Lambda 表达式是匿名函数,也就是没有名字的函数。
- 把 Lambda 表达式赋给一个变量,把变量当成函数名字来调用(Lambda 表达式没有函数名,不能通过引用来调用);
- 把 Lambda 表达式当成一个参数传入函数或者方法。
调用槽函数
代码
# 使用Lambda表达式为槽函数传递参数# fun = lambda: print('hello world') # lambda 表达式有可能没有参数,有可能有任意的多个参数,后面要跟着函数体# fun()## fun1 = lambda x, y: print(x, y) # x,y代表匿名函数参数,后面是代码# fun1('a', 'b')import sysfrom PyQt5.QtWidgets import *class LambdaSlotArg(QMainWindow):def __init__(self):super(LambdaSlotArg, self).__init__()self.initUI()passdef initUI(self):self.setWindowTitle('使用Lambda表达式为槽函数传递参数')ok = 100# 创建button控件button1 = QPushButton('按钮1')button2 = QPushButton('按钮2')# 创建水平布局,把控件加到水平布局中layout = QHBoxLayout()layout.addWidget(button1)layout.addWidget(button2)# 创建窗口,把水平布局加到窗口中,应用水平布局mainFrame = QWidget()mainFrame.setLayout(layout)# 将窗口放在主窗口中间self.setCentralWidget(mainFrame)# 将信号与槽绑定button1.clicked.connect(lambda: self.onButtonClick(10, 20)) # 为槽函数传参数,lambda表达式不用带参数button2.clicked.connect(lambda: self.onButtonClick(ok, 30)) # 为槽函数传参数,lambda表达式不用带参数passdef onButtonClick(self, m, n):print('m + n =', m+n)QMessageBox.information(self, '结果', str(m+n))passpassif __name__ == '__main__': # 只有这个文件单独执行才会调用该语句app = QApplication(sys.argv) # 传入参数main = LambdaSlotArg()main.show()sys.exit(app.exec_()) # 进入程序的主循环
结果

不调用槽函数
代码
# 使用Lambda表达式为槽函数传递参数# fun = lambda: print('hello world') # lambda 表达式有可能没有参数,有可能有任意的多个参数,后面要跟着函数体# fun()## fun1 = lambda x, y: print(x, y) # x,y代表匿名函数参数,后面是代码# fun1('a', 'b')import sysfrom PyQt5.QtWidgets import *class LambdaSlotArg(QMainWindow):def __init__(self):super(LambdaSlotArg, self).__init__()self.initUI()passdef initUI(self):self.setWindowTitle('使用Lambda表达式为槽函数传递参数')ok = 100# 创建button控件button1 = QPushButton('按钮1')button2 = QPushButton('按钮2')button3 = QPushButton('按钮3')# 创建水平布局,把控件加到水平布局中layout = QHBoxLayout()layout.addWidget(button1)layout.addWidget(button2)layout.addWidget(button3)# 创建窗口,把水平布局加到窗口中,应用水平布局mainFrame = QWidget()mainFrame.setLayout(layout)# 将窗口放在主窗口中间self.setCentralWidget(mainFrame)# 将信号与槽绑定button1.clicked.connect(lambda: self.onButtonClick(10, 20)) # 为槽函数传参数,lambda表达式不用带参数button2.clicked.connect(lambda: self.onButtonClick(ok, 30)) # 为槽函数传参数,lambda表达式不用带参数button3.clicked.connect(lambda: QMessageBox.information(self, '结果', '单击了Button3')) # lambda表达式不用带参数passdef onButtonClick(self, m, n):print('m + n =', m+n)QMessageBox.information(self, '结果', str(m+n))passpassif __name__ == '__main__': # 只有这个文件单独执行才会调用该语句app = QApplication(sys.argv) # 传入参数main = LambdaSlotArg()main.show()sys.exit(app.exec_()) # 进入程序的主循环
结果

注意
当一个信号绑定在多个槽上,是按顺序调用的。
