信号与槽基础

自定义信号实现对象之间的通信

可以传递多个参数的信号

为类添加多个信号

信号对槽的N对N连接和断开连接

为窗口添加信号

多线程更新UI数据

代码

  1. from PyQt5.QtCore import QThread,pyqtSignal,QDateTime
  2. from PyQt5.QtWidgets import QApplication,QDialog,QLineEdit
  3. import time
  4. import sys
  5. class BackendThread(QThread):
  6. update_date = pyqtSignal(str)
  7. def run(self):
  8. while True:
  9. data=QDateTime.currentDateTime()
  10. currentTime = data.toString('yyyy-MM-dd hh:mm:ss')
  11. self.update_date.emit(str(currentTime))
  12. time.sleep(1)
  13. pass
  14. pass
  15. pass
  16. class ThreadUpadteUI(QDialog):
  17. def __init__(self):
  18. QDialog.__init__(self)
  19. self.setWindowTitle('多线程更新UI数据')
  20. self.resize(400,100)
  21. self.input= QLineEdit(self)
  22. self.input.resize(400,100)
  23. self.initUI()
  24. pass
  25. def initUI(self):
  26. self.backend = BackendThread() # 定义线程
  27. self.backend.update_date.connect(self.handleDiaplay)
  28. self.backend.start()
  29. pass
  30. def handleDiaplay(self,data):
  31. self.input.setText(data)
  32. pass
  33. pass
  34. if __name__ == '__main__': # 只有这个文件单独执行才会调用该语句
  35. app = QApplication(sys.argv) # 传入参数
  36. main = ThreadUpadteUI()
  37. main.show()
  38. sys.exit(app.exec_()) # 进入程序的主循环

结果

第十五章 信号与槽 - 图1

信号与槽自动连接

使用Lambda表达式为槽传递参数

概念

  • Lambda 表达式是匿名函数,也就是没有名字的函数。
    • 把 Lambda 表达式赋给一个变量,把变量当成函数名字来调用(Lambda 表达式没有函数名,不能通过引用来调用);
    • 把 Lambda 表达式当成一个参数传入函数或者方法。

调用槽函数

代码

  1. # 使用Lambda表达式为槽函数传递参数
  2. # fun = lambda: print('hello world') # lambda 表达式有可能没有参数,有可能有任意的多个参数,后面要跟着函数体
  3. # fun()
  4. #
  5. # fun1 = lambda x, y: print(x, y) # x,y代表匿名函数参数,后面是代码
  6. # fun1('a', 'b')
  7. import sys
  8. from PyQt5.QtWidgets import *
  9. class LambdaSlotArg(QMainWindow):
  10. def __init__(self):
  11. super(LambdaSlotArg, self).__init__()
  12. self.initUI()
  13. pass
  14. def initUI(self):
  15. self.setWindowTitle('使用Lambda表达式为槽函数传递参数')
  16. ok = 100
  17. # 创建button控件
  18. button1 = QPushButton('按钮1')
  19. button2 = QPushButton('按钮2')
  20. # 创建水平布局,把控件加到水平布局中
  21. layout = QHBoxLayout()
  22. layout.addWidget(button1)
  23. layout.addWidget(button2)
  24. # 创建窗口,把水平布局加到窗口中,应用水平布局
  25. mainFrame = QWidget()
  26. mainFrame.setLayout(layout)
  27. # 将窗口放在主窗口中间
  28. self.setCentralWidget(mainFrame)
  29. # 将信号与槽绑定
  30. button1.clicked.connect(lambda: self.onButtonClick(10, 20)) # 为槽函数传参数,lambda表达式不用带参数
  31. button2.clicked.connect(lambda: self.onButtonClick(ok, 30)) # 为槽函数传参数,lambda表达式不用带参数
  32. pass
  33. def onButtonClick(self, m, n):
  34. print('m + n =', m+n)
  35. QMessageBox.information(self, '结果', str(m+n))
  36. pass
  37. pass
  38. if __name__ == '__main__': # 只有这个文件单独执行才会调用该语句
  39. app = QApplication(sys.argv) # 传入参数
  40. main = LambdaSlotArg()
  41. main.show()
  42. sys.exit(app.exec_()) # 进入程序的主循环

结果

第十五章 信号与槽 - 图2

不调用槽函数

代码

  1. # 使用Lambda表达式为槽函数传递参数
  2. # fun = lambda: print('hello world') # lambda 表达式有可能没有参数,有可能有任意的多个参数,后面要跟着函数体
  3. # fun()
  4. #
  5. # fun1 = lambda x, y: print(x, y) # x,y代表匿名函数参数,后面是代码
  6. # fun1('a', 'b')
  7. import sys
  8. from PyQt5.QtWidgets import *
  9. class LambdaSlotArg(QMainWindow):
  10. def __init__(self):
  11. super(LambdaSlotArg, self).__init__()
  12. self.initUI()
  13. pass
  14. def initUI(self):
  15. self.setWindowTitle('使用Lambda表达式为槽函数传递参数')
  16. ok = 100
  17. # 创建button控件
  18. button1 = QPushButton('按钮1')
  19. button2 = QPushButton('按钮2')
  20. button3 = QPushButton('按钮3')
  21. # 创建水平布局,把控件加到水平布局中
  22. layout = QHBoxLayout()
  23. layout.addWidget(button1)
  24. layout.addWidget(button2)
  25. layout.addWidget(button3)
  26. # 创建窗口,把水平布局加到窗口中,应用水平布局
  27. mainFrame = QWidget()
  28. mainFrame.setLayout(layout)
  29. # 将窗口放在主窗口中间
  30. self.setCentralWidget(mainFrame)
  31. # 将信号与槽绑定
  32. button1.clicked.connect(lambda: self.onButtonClick(10, 20)) # 为槽函数传参数,lambda表达式不用带参数
  33. button2.clicked.connect(lambda: self.onButtonClick(ok, 30)) # 为槽函数传参数,lambda表达式不用带参数
  34. button3.clicked.connect(lambda: QMessageBox.information(self, '结果', '单击了Button3')) # lambda表达式不用带参数
  35. pass
  36. def onButtonClick(self, m, n):
  37. print('m + n =', m+n)
  38. QMessageBox.information(self, '结果', str(m+n))
  39. pass
  40. pass
  41. if __name__ == '__main__': # 只有这个文件单独执行才会调用该语句
  42. app = QApplication(sys.argv) # 传入参数
  43. main = LambdaSlotArg()
  44. main.show()
  45. sys.exit(app.exec_()) # 进入程序的主循环

结果

第十五章 信号与槽 - 图3

注意

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

代码

结果

使用Partial对象为槽传递参数

Override槽函数

多窗口交互:不使用信号和槽

多窗口交互:使用信号和槽