Python PyQt5学习之自定义信号
作者:Yunlord 发布时间:2022-01-06 12:03:52
PyQ5已经自动定义了很多QT自建的信号。但是在实际的使用中为了灵活使用信号与槽机制,可以根据需要自定义信号。通过使用pyqtSignal()方法定义新的信号,新的信号作为类的属性。
自定义signal说明:
新的信号应该定义在QObject的子类中。新的信号必须作为定义类的一部分,不允许将信号作为类的属性在类定义之后通过动态的方式进行添加。通过这种方式新的信号才能自动的添加到QMetaObject类中。这就意味这新定义的信号将会出现在Qt Designer,并且可以通过QMetaObject API实现内省。
自定义信号的发射,通过emit()方法类实现
自定义信号的一般流程如下:
定义信号
定义槽函数
绑定信号和槽
发射信号
代码示例
import sys
from PyQt5.QtCore import pyqtSignal, QObject, Qt, pyqtSlot
from PyQt5.QtWidgets import QWidget, QApplication, QGroupBox, QPushButton, QLabel, QCheckBox, QSpinBox, QHBoxLayout, QComboBox, QGridLayout
class SignalEmit(QWidget):
helpSignal = pyqtSignal(str)
printSignal = pyqtSignal(list)
#声明一个多重载版本的信号,包括了一个带int和str类型参数的信号,以及带str参数的信号
previewSignal = pyqtSignal([int,str],[str])
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.creatContorls("打印控制:")
self.creatResult("操作结果:")
layout = QHBoxLayout()
layout.addWidget(self.controlsGroup)
layout.addWidget(self.resultGroup)
self.setLayout(layout)
self.helpSignal.connect(self.showHelpMessage)
self.printSignal.connect(self.printPaper)
self.previewSignal[str].connect(self.previewPaper)
self.previewSignal[int,str].connect(self.previewPaperWithArgs)
self.printButton.clicked.connect(self.emitPrintSignal)
self.previewButton.clicked.connect(self.emitPreviewSignal)
self.setGeometry(300, 300, 290, 150)
self.setWindowTitle('defined signal')
self.show()
def creatContorls(self,title):
self.controlsGroup = QGroupBox(title)
self.printButton = QPushButton("打印")
self.previewButton = QPushButton("预览")
numberLabel = QLabel("打印份数:")
pageLabel = QLabel("纸张类型:")
self.previewStatus = QCheckBox("全屏预览")
self.numberSpinBox = QSpinBox()
self.numberSpinBox.setRange(1, 100)
self.styleCombo = QComboBox(self)
self.styleCombo.addItem("A4")
self.styleCombo.addItem("A5")
controlsLayout = QGridLayout()
controlsLayout.addWidget(numberLabel, 0, 0)
controlsLayout.addWidget(self.numberSpinBox, 0, 1)
controlsLayout.addWidget(pageLabel, 0, 2)
controlsLayout.addWidget(self.styleCombo, 0, 3)
controlsLayout.addWidget(self.printButton, 0, 4)
controlsLayout.addWidget(self.previewStatus, 3, 0)
controlsLayout.addWidget(self.previewButton, 3, 1)
self.controlsGroup.setLayout(controlsLayout)
def creatResult(self,title):
self.resultGroup = QGroupBox(title)
self.resultLabel = QLabel("")
layout = QHBoxLayout()
layout.addWidget(self.resultLabel)
self.resultGroup.setLayout(layout)
def emitPreviewSignal(self):
if self.previewStatus.isChecked() == True:
self.previewSignal[int,str].emit(1080," Full Screen")
elif self.previewStatus.isChecked() == False:
self.previewSignal[str].emit("Preview")
def emitPrintSignal(self):
pList = []
pList.append(self.numberSpinBox.value ())
pList.append(self.styleCombo.currentText())
self.printSignal.emit(pList)
def printPaper(self,list):
self.resultLabel.setText("Print: "+"份数:"+ str(list[0]) +" 纸张:"+str(list[1]))
def previewPaperWithArgs(self,style,text):
self.resultLabel.setText(str(style)+text)
def previewPaper(self,text):
self.resultLabel.setText(text)
def keyPressEvent(self, event):
if event.key() == Qt.Key_F1:
self.helpSignal.emit("help message")
def showHelpMessage(self,message):
self.resultLabel.setText(message)
#self.statusBar().showMessage(message)
if __name__ == '__main__':
app = QApplication(sys.argv)
dispatch = SignalEmit()
sys.exit(app.exec_())
样例说明:
通过一个模拟打印的界面来详细说明一下关于信号的自定义,在打印的时候可以设定打印的分数,纸张类型,触发“打印”按钮之后,将执行结果显示到右侧;通过全屏预览QCheckBox来选择是否通过全屏模式进行预览,将执行结果显示到右侧。
通过点击F1快捷键,可以显示helpMessage信息。
界面分析:
该界面主要由两个部分组成:一个是打印控制,另一个是操作结果。
通过QHBoxLayout组合起来,如下所示:
layout = QHBoxLayout()
layout.addWidget(self.controlsGroup)
layout.addWidget(self.resultGroup)
self.setLayout(layout)
然后通过creatContorls定义“打印控制”界面,
def creatContorls(self,title):
self.controlsGroup = QGroupBox(title)
self.printButton = QPushButton("打印")
self.previewButton = QPushButton("预览")
numberLabel = QLabel("打印份数:")
pageLabel = QLabel("纸张类型:")
self.previewStatus = QCheckBox("全屏预览")
self.numberSpinBox = QSpinBox()
self.numberSpinBox.setRange(1, 100)
self.styleCombo = QComboBox(self)
self.styleCombo.addItem("A4")
self.styleCombo.addItem("A5")
controlsLayout = QGridLayout()
controlsLayout.addWidget(numberLabel, 0, 0)
controlsLayout.addWidget(self.numberSpinBox, 0, 1)
controlsLayout.addWidget(pageLabel, 0, 2)
controlsLayout.addWidget(self.styleCombo, 0, 3)
controlsLayout.addWidget(self.printButton, 0, 4)
controlsLayout.addWidget(self.previewStatus, 3, 0)
controlsLayout.addWidget(self.previewButton, 3, 1)
self.controlsGroup.setLayout(controlsLayout)
QSpinBox是一个计数器控件,允许用户选择一个整数值通过单击向上向下或者按键盘上的上下键来增加减少当前显示的值,当然用户也可以输入值。
QComboBox是一个集按钮和下拉选项于一体的控件,也称做下拉列表框。
然后通过creatResult定义“操作结果”界面:
def creatResult(self,title):
self.resultGroup = QGroupBox(title)
self.resultLabel = QLabel("")
layout = QHBoxLayout()
layout.addWidget(self.resultLabel)
self.resultGroup.setLayout(layout)
代码分析:
helpSignal = pyqtSignal(str)
printSignal = pyqtSignal(list)
#声明一个多重载版本的信号,包括了一个带int和str类型参数的信号,以及带str参数的信号
previewSignal = pyqtSignal([int,str],[str])
通过pyqtSignal()定义了三个信号,helpSignal,printSignal,previewSignal。其中:
helpSignal 为str参数类型的信号。
printSignal 为list参数类型的信号。
previewSignal为一个多重载版本的信号,包括了一个带int和str类型参数的信号,以及str类行的参数。
self.helpSignal.connect(self.showHelpMessage)
self.printSignal.connect(self.printPaper)
self.previewSignal[str].connect(self.previewPaper)
self.previewSignal[int,str].connect(self.previewPaperWithArgs)
self.printButton.clicked.connect(self.emitPrintSignal)
self.previewButton.clicked.connect(self.emitPreviewSignal)
绑定信号和槽。
着重说明一下多重载版本的信号的绑定,previewSignal有两个版本previewSignal(str),previewSignal(int,str)。由于存在两个版本,从因此在绑定的时候需要显式的指定信号和槽的绑定关系。
具体如下:
self.previewSignal[str].connect(self.previewPaper) self.previewSignal[int,str].connect(self.previewPaperWithArgs)
其中[str]参数的previewSignal信号绑定previewPaper();[int,str]的previewSignal信号绑定previewPaperWithArgs()
def emitPreviewSignal(self):
if self.previewStatus.isChecked() == True:
self.previewSignal[int,str].emit(1080," Full Screen")
elif self.previewStatus.isChecked() == False:
self.previewSignal[str].emit("Preview")
多重载版本的信号的发射也需要制定对应发射的版本,类似同信号的版定。
def emitPrintSignal(self):
pList = []
pList.append(self.numberSpinBox.value ())
pList.append(self.styleCombo.currentText())
self.printSignal.emit(pList)
如代码中所示,在信号发射的时候可以传递python数据类型的参数,在本例中传递list类型的参数pList。
def keyPressEvent(self, event):
if event.key() == Qt.Key_F1:
self.helpSignal.emit("help message")
通过复写keyPressEvent()方法,将F1快捷键进行功能的拓展。在windows的大部分应用,我们都会使用一些快捷键来快速的完成某些特定的功能。比如F1键,会快速调出帮助界面,那就可以复写keyPressEvent()方法来模拟发送所需的信号,来完成对应任务。
注意事项:
1.自定义的信号在init()函数之前定义
2.自定义型号可以传递,str、int、list、object、float、tuple、dict等很多类型的参数
3.注意signal和slot的调用逻辑,避免signal和slot之间出现死循环。如在slot方法中继续发射该信号
来源:https://blog.csdn.net/kobepaul123/article/details/122972224
猜你喜欢
- 用于操作数据库的SQL一般分为两种,一种是查询语句,也就是我们所说的 SELECT语句,另外一种就是更新语句,也叫做数据操作语句。言外之 意
- 首先要解释一下:“极致之美”不是说月儿的这篇文章,因为本人还没有自大到这种程度:P,它形容的是Lisp和javascript结合的优美形态。
- 上个周末去书店时碰巧看到了AS3 CookeBook,我记得在apollo的alpha版快出来的时候,7yue就推荐过这个小册子,只不过我已
- 这篇文章主要介绍了Python类如何定义私有变量,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以
- PHP有一组进程控制函数(编译时需要–enable-pcntl与posix扩展),使得php能实现跟c
- 在使用Python处理数据时,经常需要对数据筛选。这是在对时间筛选时,判断两列时间是否相差一年,如果是,则返回符合条件的所有列。data原始
- ASP访问数据库的方式有哪些?在ASP中可以通过三种方式访问数据库:1、IDC(Internet Database Connec
- 阅读上一篇:FrontPage XP设计教程3——网页的布局 FrontPage XP可以保证用户设计网页与不同的浏览器兼容,它所提供的样式
- 前言作为Web开发人员,在 Web浏览器中存储数据以改善用户体验和提升Web应用程序性能是非常常见的。在大多数情况下,可供我们使用就是Loc
- 清除浮动这个问题的提出,在现在来说应该算是一个非常古老的问题了,很多人对解决办法估计也能烂记于心了,但是我这个落后了不少的前端开发程序员,太
- 前言大家应该都有所体会,对于字符串型的IP存入数据库中,实在是个即浪费空间又浪费性能的家伙,所以可爱的人们想出来将IP转换为整型存储。MyS
- 首先,了解下原理。1,提供文本框进行查询内容的输入2,将查询信息提交页面程序处理3,程序页主要作用:接受查询信息,根据此信息调用特定的SQL
- 本文实例为大家分享了python使用Matplotlib画条形图的具体代码,供大家参考,具体内容如下数据中国的四个直辖市分别为北京市、上海市
- 一、configparser模块是什么可以用来操作后缀为 .ini 的配置文件;python标准库(就是python自带的意思,无需安装)二
- 原文地址:30 Days of Mootools 1.2 Tutorials - Day 4 - Functions函数和MooTools
- 语法: ROW_NUMBER() OVER([ <partition_by_clause>] <order_by_clau
- 互联网是一个飞速发展的行业,任何的止步不前都会导致被淘汰,只是时间早晚的问题,所以一个公司的学习与创新能力是非常重要的,特别是对于一个年轻的
- 字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,
- 平常我们使用js代码获取的时间都是客户端的时间,那么有什么办法在浏览器中显示的是服务器断的时间吗?请看下面代码:<span id=&q
- 这里以安装简单的nonebot库为例子欧克,简明扼要,拿走点赞哟:大家想要的豆瓣源如下:因为有几个,但在这里还是建议使用国内的豆瓣源,本人感