文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

PythonPyQt5学习之自定义信号

2024-04-02 19:55

关注

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。其中:

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信号内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯