一文详解PyQt5中信号(Signal)与槽(Slot)
作者:SongYuLong的博客 发布时间:2022-06-27 19:53:08
标签:PyQt5,信号,槽
信号与槽介绍
信号(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_())
来源:https://blog.csdn.net/songyulong8888/article/details/128083678
0
投稿
猜你喜欢
- 使用windows API使用PIL中的ImageGrab模块下面对两者的特点和用法进行详细解释。一、Python调用windows API
- 遇到这样一个需求,有一张表,要给这张表新增一个字段delta,delta的值等于每行的c1列的值减去上一行c1列的值。我的解决方案,可以通过
- 前言用过Pandas和openpyxl库的同学都知道,这两个库是相互互补的。Pandas绝对是Python中处理Excel最快、最好用的库,
- 这年头如果用 python3 做条形码的,肯定(推荐)用 pystrich 。这货官方文档貌似都没写到支持 Code128 ,但是居然有这个
- #-*- coding:utf-8 -*-import osif __name__ == '__main__':
- 在Go语言中,我们可以使用for、append()和copy()进行数组拷贝,对于某些对性能比较敏感且数组拷贝比较多的场景,我们可以会对拷贝
- Python列表List(列表) 是 Python 中使用最频繁的数据类型。列表可以完成大多数集合类的数据结构实现。它支持字符,数字,字符串
- 这篇文章主要介绍了Python列表切片常用操作实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋
- 哈夫曼树原理秉着能不写就不写的理念,关于哈夫曼树的原理及其构建,还是贴一篇博客吧。https://www.jb51.net/article/
- 之前遇到一个场景是这样的:我在自己的电脑上需要用mongodb图形客户端,但是mongodb的服务器地址没有对外网开放,只能通过先登录主机A
- 在使用ASP来进行后端的数据合法性校验的时候,有些人为满足不同环境下面的数据校验,编写了很多的函数来实现,比如,我们想要校验用户输入的URL
- 这篇文章主要介绍了Python tkinter常用操作代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,
- 1.背景项目需求,要求获得github的repo的api,以便可以提取repo的数据进行分析。研究了一天,终于解决了这个问题,虽然效率还是比
- 本文实例为大家分享了python实现文件批量重命名的具体代码,供大家参考,具体内容如下代码:# -*- coding:utf-8 -*-im
- 又发现一个IE不标准的地方,unshift方法会返回新数组的长度,但IE6与IE7则返回undefined。var a = [3,2,1,4
- Pycharm代码运行调试,具体内容如下1、准备工作(1)Python版本为2.7或者更高版本(2)已经创建了一个Python工程并且添加了
- 在来回切换中英文输入法的时候连按两下shift总是会蹦出来全局搜索框真的很是麻烦,现在是把这个框给禁用掉1.按ctrl+shift+a,弹出
- 一、引言这个五一假期自驾回老家乡下,家里没装宽带,用手机热点方式访问网络。这次回去感觉4G信号没有以前好,通过百度查找小说最新更新并打开小说
- 首先,创建一个DataFrame格式数据作为举例数据。# 创建一个DataFrame格式数据data = {'a': [
- python对Ref文档进行去重首先将txt文档提取到Excel表格中筛选出重复项,并且整理到txt中:需要去重的目标txt也准备好:接下来