侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

pyqt5自定义信号实例解析

Python  /  管理员 发布于 5年前   282

本文研究的主要是pyqt5自定义信号实例解析的相关内容,具体介绍如下。

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

自定义signal说明:

pyqtSignal()方法原型(PyQt官网的定义):

PyQt5.QtCore.pyqtSignal(types[, name[, revision=0[, arguments=[]]]])
Create one or more overloaded unbound signals as a class attribute.

Parameters:
types C the types that define the C++ signature of the signal. Each type may be a Python type object or a string that is the name of a C++ type. Alternatively each may be a sequence of type arguments. In this case each sequence defines the signature of a different signal overload. The first overload will be the default.

name C the name of the signal. If it is omitted then the name of the class attribute is used. This may only be given as a keyword argument.

revision C the revision of the signal that is exported to QML. This may only be given as a keyword argument.

arguments C the sequence of the names of the signal's arguments that is exported to QML. This may only be given as a keyword argument.
Return type: an unbound signal

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

通过下面的例子,了解一下关于signal的定义:

from PyQt5.QtCore import QObject, pyqtSignalclass NewSignal(QObject):  # 定义了一个“closed”信号,该信号没有参数据  closed= pyqtSignal()  # 定义了一个"range_changed"信号,该信号有两个int类型的参数  range_changed = pyqtSignal(int, int, name='rangeChanged')

自定义信号的发射,通过emit()方法类实现,具体参见该函数的原型:

emit(*args)
Parameters: args C the optional sequence of arguments to pass to any connected slots.

通过下面的例子,了解一下关于emit()的使用:

from PyQt5.QtCore import QObject, pyqtSignalclass NewSignal(QObject):  # 一个valueChanged的信号,该信号没有参数.  valueChanged = pyqtSignal()  def connect_and_emit_valueChanged(self):    # 绑定信号和槽函数    self.valueChanged.connect(self.handle_valueChanged)    # 发射信号.    self.trigger.emit()  def handle_valueChanged(self):    print("trigger signal received")

示例说明:

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

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

通过代码示例来了解一下信号的自定义过程:

#-*- coding:utf-8 -*-'''defined Signal'''__author__ = 'Tony Zhu'import sysfrom PyQt5.QtCore import pyqtSignal, QObject, Qt, pyqtSlotfrom PyQt5.QtWidgets import QWidget, QApplication, QGroupBox, QPushButton, QLabel, QCheckBox, QSpinBox, QHBoxLayout, QComboBox, QGridLayoutclass 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信息。

代码分析:

L12~15:

  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()

L72~76:

  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")

多重载版本的信号的发射也需要制定对应发射的版本,类似同信号的版定。

L78~82:

  def emitPrintSignal(self):    pList = []    pList.append(self.numberSpinBox.value ())    pList.append(self.styleCombo.currentText())    self.printSignal.emit(pList)

如代码中所示,在信号发射的时候可以传递python数据类型的参数,在本例中传递list类型的参数pList.

L93~96:

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

总结

以上就是本文关于pyqt5自定义信号实例解析的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!


  • 上一条:
    scrapy爬虫完整实例
    下一条:
    pyqt5简介及安装方法介绍
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客