一文详解PyQt5中信号(Signal)与槽(Slot)
更新时间:2022年12月2日 10:45 点击:236 作者:SongYuLong的博客
信号与槽介绍
信号(Signal)与槽(Slot)是Qt中的核心机制,也是在PyQt编程中对象之间进行通信的机制。PyQt的窗口控件类有很多内置信号,开发者也可以添加自定义信号。信号与槽有如下特点:
- 一个信号可以连接多个槽。
- 一个信号可以连接另一个信号。
- 信号参数可以使任何Python类型。
- 一个槽可以连接到多个信号。
- 信号与槽的连接方式可以是同步连接,也可以是异步连接。
- 信号与槽的连接可能会跨线程。
- 信号可以断开连接。
内置信号与槽的使用
这里演示了内置clicked信号连接槽函数的使用
import sys from PyQt5.QtWidgets import QPushButton, QApplication, QWidget, QMessageBox app = QApplication(sys.argv) widget = QWidget() def showMsg(): QMessageBox.information(widget, "信息提示框", "Ok,弹出测试信息") btn = QPushButton("测试点击按钮", widget) btn.clicked.connect(showMsg) widget.show() sys.exit(app.exec_())
自定义信号与槽的使用
import sys from PyQt5.QtCore import QObject, pyqtSignal # 信号对象 class QTypeSignal(QObject): # 定义一个信号 sendmsg = pyqtSignal(object) def __init__(self): super(QTypeSignal, self).__init__() def run(self): # 发射信号 self.sendmsg.emit('Hello PyQt5') # 槽对象 class QTypeSlot(QObject): def __init__(self): super(QTypeSlot, self).__init__() # 槽对象中的槽函数 def get(self, msg): print("QSlot get msg => " + msg) if __name__ == "__main__": send = QTypeSignal() slot = QTypeSlot() # 1 print("---把信号绑定到槽函数上---") send.sendmsg.connect(slot.get) send.run() # 2 print('---把信号与槽函数断开---') send.sendmsg.disconnect(slot.get) send.run()
自定义信号和内置槽函数
import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtCore import Qt class WinForm (QWidget): # 自定义信号,不带参数 button_clicked_signal = pyqtSignal() def __init__(self, parent=None): super(WinForm, self).__init__(parent) self.setWindowTitle("自定义信号和内置槽函数示例") self.resize(330, 50) btn = QPushButton("关闭", self) # 连接信号与槽函数 btn.clicked.connect(self.btn_clicked) # 接收信号,连接到槽函数 self.button_clicked_signal.connect(self.close) def btn_clicked(self): # 发送自定义信号,无参数 self.button_clicked_signal.emit() if __name__ == "__main__": app = QApplication(sys.argv) win = WinForm() win.show() sys.exit(app.exec_())
自定义信号和自定义槽函数
import sys from PyQt5.QtCore import * from PyQt5.QtWidgets import * class WinForm(QWidget): # 自定义信号,无参数 button_clicked_signal = pyqtSignal() def __init__(self, parent= None): super(WinForm, self).__init__(parent) self.setWindowTitle("自定义信号和槽函数示例") self.resize(350, 50) btn = QPushButton("关闭", self) btn.clicked.connect(self.btn_clicked) self.button_clicked_signal.connect(self.btn_close) def btn_clicked(self): self.button_clicked_signal.emit() def btn_close(self): self.close() if __name__ == "__main__": app = QApplication(sys.argv) win = WinForm() win.show() sys.exit(app.exec_())
自定义有参信号
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(CustSignal, self).__init__(parent) # 将信号连接到指定的槽函数 self.signal1.connect(self.signalCall1) self.signal2.connect(self.signalCall2) self.signal3.connect(self.signalCall4) 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(100) self.signal3.emit(200, 'hello') self.signal4.emit([1,2,3,4,5,6]) self.signal5.emit({"name":"xiaowang", "age":"25"}) self.signal6[int, str].emit(300, 'hello world') self.signal6[str].emit('hello pyqt') def signalCall1(self): print('signal1 emit') def signalCall2(self, val): print('signal3 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()
使用自定义信号参数
对于clicked信号来说他是没有参数的,如果连接的槽函数希望可以接收参数,如果直接连接有参数的槽函数会出错,因为信号发出的参数个数一定要大于槽函数接收的参数个数。这里有两种解决方法:
1.使用lambda
2.使用functools模块中的partial函数
import sys from PyQt5.QtCore import * from PyQt5.QtWidgets import * from functools import partial, partialmethod class WinForm(QMainWindow): def __init__(self, parent=None): super(WinForm, self).__init__(parent) self.setWindowTitle("有参槽函数接收无参信号的解决方法") button1 = QPushButton("Button 1") button2 = QPushButton("Button 2") # 对于clicked信号来说他是没有参数的,如果连接的槽函数希望可以接收参数,如果直接连接有参数 # 的槽函数会出错,因为信号发出的参数个数一定要大于槽函数接收的参数个数。这里有两种解决方法: # 1.使用lambda # 2.使用functools模块中的partial函数 # 使用lambda button1.clicked.connect(lambda: self.onButtonClick(1)) # 使用functools模块中的partial函数 button2.clicked.connect(partial(self.onButtonClick, 2)) layout = QHBoxLayout() layout.addWidget(button1) layout.addWidget(button2) mainwidget = QWidget() mainwidget.setLayout(layout) self.setCentralWidget(mainwidget) 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_())
装饰器信号与槽
@PyQt5.QtCore.pyqtSlot(参数)
def on_发送者对象名称_发射信号名称(self, 参数):
pass
必须先执行了这行代码:QtCore.QMetaObject.connectSlotsByName(self)
from PyQt5 import QtCore from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton, QMessageBox import sys # 装饰器信号与槽 # @PyQt5.QtCore.pyqtSlot(参数) # def on_发送者对象名称_发射信号名称(self, 参数): # pass # # 必须要先执行这行代码:QtCore.QMetaObject.connectSlotsByName(self) class CustWidget(QWidget): def __init__(self, parent=None): super(CustWidget, self).__init__(parent) self.setWindowTitle("装饰器信号与槽Demo") self.resize(350, 50) self.okButton = QPushButton("OK", self) # 使用setObjectName设置对象名称 self.okButton.setObjectName("okButton") layout = QHBoxLayout() layout.addWidget(self.okButton) self.setLayout(layout) QtCore.QMetaObject.connectSlotsByName(self) @QtCore.pyqtSlot() def on_okButton_clicked(self): print("单击了OK按钮") QMessageBox.information(self, "信息提示框", "单击了OK按钮") if __name__ == "__main__": app = QApplication(sys.argv) win = CustWidget() win.show() sys.exit(app.exec_())
信号与槽的断开和连接
import sys from PyQt5.QtCore import * from PyQt5.QtWidgets import * # 信号与槽断开连接 class SignalClass(QObject): # 声明无参数的信号 signal1 = pyqtSignal() # 声明带一个int类型参数的信号 signal2 = pyqtSignal(int) def __init__(self, parent=None): super(SignalClass, self).__init__(parent) # 将信号signal1连接到sig1Call和sig2Call这两个槽函数 self.signal1.connect(self.sig1Call) self.signal1.connect(self.sig2Call) # 将signal2连接到signal1 self.signal2.connect(self.signal1) # 发射信号 self.signal1.emit() self.signal2.emit(1) # 断开signal1,signal2信号与各槽函数的连接 self.signal1.disconnect(self.sig1Call) self.signal1.disconnect(self.sig2Call) self.signal2.disconnect(self.signal1) # 将信号signal1和signal2连接到同一个槽函数sig1Call self.signal1.connect(self.sig1Call) self.signal2.connect(self.sig1Call) # 再次发射信号 self.signal1.emit() self.signal2.emit(2) def sig1Call(self): print('signal-1 emit') def sig2Call(self): print('signal-2 emit') if __name__ == "__main__": signal = SignalClass()
多线程中信号与槽的使用
import sys from PyQt5.QtWidgets import QApplication, QWidget from PyQt5.QtCore import QThread, pyqtSignal class Main(QWidget): def __init__(self, parent=None): super(Main, self).__init__(parent) # 创建一个线程实例并设置名称,变量,信号与槽 self.thread = MyThread() self.thread.setIdentity("thread1") self.thread.sinOut.connect(self.outText) self.thread.setVal(6) def outText(self, text): print(text) class MyThread(QThread): sinOut = pyqtSignal(str) def __init__(self, parent=None): super(MyThread, self).__init__(parent) self.identity = None def setIdentity(self, text): self.identity = text def setVal(self, val): self.times = int(val) # 执行线程run方法 self.start() def run(self): while self.times > 0 and self.identity: # 发射信号 self.sinOut.emit(self.identity + "==>" + str(self.times)) self.times -= 1 if __name__ == '__main__': app = QApplication(sys.argv) main = Main() main.show() sys.exit(app.exec_())
以上就是一文详解PyQt5中信号(Signal)与槽(Slot)的详细内容,更多关于PyQt5信号 槽的资料请关注猪先飞其它相关文章!
原文出处:https://blog.csdn.net/songyulong8888/article/details/1280836
相关文章
- 这篇文章主要给大家介绍了关于Vue中slot-scope的深入理解,这个教程非常适合初学者,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-17
- 这篇文章主要介绍了Vue中的插槽,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-10-19
pyqt5 textEdit、lineEdit操作的示例代码
这篇文章主要介绍了pyqt5 textEdit、lineEdit操作的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-08-12- 这篇文章主要介绍了PyQt5结合matplotlib绘图的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-15
- 这篇文章主要为大家介绍了python编程使用PyQt5如何创建按钮及触发点击事件的示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步...2021-10-29
- 这篇文章主要介绍了Pyqt5 实现窗口缩放,控件在窗口内自动伸缩的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09
- 这篇文章主要介绍了vue 插槽简介及使用示例,帮助大家更好的理解和学习vue框架,感兴趣的朋友可以了解下...2020-11-19
- 这篇文章主要介绍了PyQt5-QDateEdit的简单使用操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-12
- 最近要做个网页图片批量下载工具,然后需要一个页面显示网页上的所有图片供用户勾选,再根据勾选的内容来下载指定图片,其中就涉及到要到同时显示多张图片,本文就来介绍一下...2021-06-11
- 这篇文章主要介绍了PyQt5 实现给无边框widget窗口添加背景图片的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09
- 最近做了一个窗口程序,那么能不能将其生成一个可执行文件,本文就介绍一下pyqt5打包成exe可执行文件的方法,感兴趣的可以了解一下...2021-05-15
详解PyQt5中textBrowser显示print语句输出的简单方法
这篇文章主要介绍了详解PyQt5中textBrowser显示print语句输出的简单方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-08-07- 这篇文章主要为大家介绍了PyQt5使用mimeData实现拖拽事件的教程示例解析,系列文章详见文中跳转链接,有需要的朋友可以借鉴参考下,希望能够有所帮助...2021-10-29
- 这篇文章主要介绍了PyQt5 显示超清高分辨率图片的方法,帮助大家更好的理解和阿学习使用pyqt5,感兴趣的朋友可以了解下...2021-04-10
- 这篇文章主要介绍了Pycharm配置PyQt5环境的教程,本文通过图文实例详解给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-05-10
- 信号和槽是Qt特有的信息传输机制,本文主要介绍了浅谈Qt信号与槽的各种连接方式,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-02
- 本篇文章是对使用c语言实现HUP信号重启进程的方法进行了详细的分析介绍,需要的朋友参考下...2020-04-25
- 这篇文章主要介绍了C++ 信号处理的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-10
- 这篇文章主要介绍了Perl脚本实现检测主机心跳信号功能,本文代码也可作为perl串口通信的实例,需要的朋友可以参考下...2020-06-29
- 这篇文章主要介绍了解决PyQt5 无边框后窗口的移动问题,具有很好的参考价值,希望对大家有所帮助,一起跟随小编过来看看吧...2021-03-09