Python PyQt5学习之自定义信号

 更新时间:2022年03月02日 10:31:53   作者:Yunlord  
PyQ5已经自动定义了很多QT自建的信号。但是在实际的使用中为了灵活使用信号与槽机制,可以根据需要自定义信号。本文就将为大家详细讲讲PyQt5自定义信号,感兴趣的可以了解一下

PyQ5已经自动定义了很多QT自建的信号。但是在实际的使用中为了灵活使用信号与槽机制,可以根据需要自定义信号。通过使用pyqtSignal()方法定义新的信号,新的信号作为类的属性。

自定义signal说明:

新的信号应该定义在QObject的子类中。新的信号必须作为定义类的一部分,不允许将信号作为类的属性在类定义之后通过动态的方式进行添加。通过这种方式新的信号才能自动的添加到QMetaObject类中。这就意味这新定义的信号将会出现在Qt Designer,并且可以通过QMetaObject API实现内省。

自定义信号的发射,通过emit()方法类实现

自定义信号的一般流程如下:

  1. 定义信号
  2. 定义槽函数
  3. 绑定信号和槽
  4. 发射信号

代码示例

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方法中继续发射该信号

到此这篇关于Python PyQt5学习之自定义信号的文章就介绍到这了,更多相关Python PyQt5信号内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • windows server 2008 r2 标准版安装python环境

    windows server 2008 r2 标准版安装python环境

    本文主要介绍了windows server 2008 r2 标准版安装python环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • 利用Python-iGraph如何绘制贴吧/微博的好友关系图详解

    利用Python-iGraph如何绘制贴吧/微博的好友关系图详解

    这篇文章主要给大家介绍了关于利用Python-iGraph如何绘制贴吧/微博好友关系图的相关资料,文中显示介绍了在windows系统下安装python-igraph的步骤,然后通过示例代码演示了绘制好友关系图的方法,需要的朋友可以参考下。
    2017-11-11
  • pytorch中torch.topk()函数的快速理解

    pytorch中torch.topk()函数的快速理解

    我们在做分类算法时,时常见到@acc1和@acc5的情况,@acc1比较容易实现,但是一直苦于@acc5算法的实现,在此为大家提供一种@topk的实现方法,这篇文章主要给大家介绍了关于pytorch中torch.topk()函数的快速理解,需要的朋友可以参考下
    2022-02-02
  • Python中的五个神仙级函数一起来看看

    Python中的五个神仙级函数一起来看看

    这篇文章主要为大家介绍了Python中的五个神仙级函数,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • pytorch中retain_graph==True的作用说明

    pytorch中retain_graph==True的作用说明

    这篇文章主要介绍了pytorch中retain_graph==True的作用说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • Python 实现任意区域文字识别(OCR)操作

    Python 实现任意区域文字识别(OCR)操作

    这篇文章主要介绍了Python 实现任意区域文字识别(OCR)操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • Python实现在线音乐播放器

    Python实现在线音乐播放器

    这篇文章主要为大家详细介绍了Python实现在线音乐播放器的相关资料,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-03-03
  • Python实现url长短链接的转换

    Python实现url长短链接的转换

    短链接,通俗来说,就是将长的URL网址,通过程序计算等方式,转换为简短的网址字符串。本文将用Python语言实现这一效果,需要的可以参考一下
    2022-11-11
  • Python3实现的画图及加载图片动画效果示例

    Python3实现的画图及加载图片动画效果示例

    这篇文章主要介绍了Python3实现的画图及加载图片动画效果,结合实例形式分析了Python3基于tkinter库进行图片加载动画效果的相关实现与使用技巧,需要的朋友可以参考下
    2018-01-01
  • python出现更新库失败A new release of pip is available: 23.0.1 -> 23.3解决办法

    python出现更新库失败A new release of pip is available: 23.0.

    学习了Python我们知道它自带了很多的库,同时我们还需要对某个库进行升级,这篇文章主要给大家介绍了关于python出现更新库失败A new release of pip is available: 23.0.1 -> 23.3的解决办法,需要的朋友可以参考下
    2024-03-03

最新评论