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

(0)

相关推荐

  • python GUI库图形界面开发之PyQt5信号与槽的高级使用技巧(自定义信号与槽)详解与实例

    PyQt5信号与槽高级自定义信号与槽 所谓高级自定义信号与槽,指的就是我们可以以自己喜欢的方式定义信号与槽函数,并传递参数,自定义信号的一般流程如下 定义信号 定义槽函数 连接信号与槽函数 发射信号 1.定义信号 通过类成员变量定义信号对象 #无参数的信号 signal1=pyqtSignal() #带一个参数(整数)的信号 signal2=pyqtSignal(int) #带两个参数(整数,字符串)的信号 signal3=pyqtSignal(int,str) #带一个参数(列表)的信号 si

  • python GUI库图形界面开发之PyQt5信号与槽的高级使用技巧装饰器信号与槽详细使用方法与实例

    装饰器信号与槽 所谓装饰器信号与槽,就是通过装饰器的方法来定义信号与槽函数,具体的使用方法如下 @PyQt5.QtCore.pyqtSlot(参数) def on_发送者对象名称_发射信号名称(self,参数): pass 这种方法有效的前提是下面的函数已经执行: QMetaObject.connectSlotsByName(QObject) 在上面的代码中,'发送者对象名称'就是使用setObjectName函数设置的名称,因此自定义槽函数的命名规则也可以看做:on+使用setObjectNa

  • python GUI库图形界面开发之PyQt5信号与槽基础使用方法与实例

    信号与槽有三种使用方法 第一种:内置信号与槽的使用 第二种:自定义信号与槽的使用 第三种:装饰器的信号与槽的使用 一: 内置信号与槽的使用 内置信号与槽的使用,是指在发射信号时,使用窗口控件的函数,而不是自定义的函数,这种也是我们前面用的最多的,下面简单的一个实例,大家就会明白 import sys from PyQt5.QtWidgets import QMessageBox,QPushButton,QApplication,QWidget app=QApplication(sys.argv)

  • python GUI库图形界面开发之PyQt5信号与槽机制、自定义信号基础介绍

    信号和槽机制是 QT 的核心机制,要精通 QT 编程就必须对信号和槽有所了解.信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性,也是 QT 区别于其它工具包的重要地方. 在linux.windows等 GUI 工具包中,GUI组件都会注册回调函数用于处理组件所触发的动作,通常是注册对应的函数的函数指针.在之前关于Button的文章中提到了信号与槽的机制的使用,通过该机制可以很好的将组件的信号(如button的clocked.toggled.pressed等)和处理该信号的槽关

  • python GUI库图形界面开发之PyQt5信号与槽基本操作

    信号与槽基本操作 进入Qt Designer,加入控件,本文以按钮为例. 按F4开始后,选择需要加入信号与槽的按钮,如下图所示该按钮会变红,按住鼠标拉出一条红线,若该按钮需控制旁边的label,则红线连接到label上(图1),若对框体(MainWindow)进行操作,则链接到框体上,会出现一个像物理中"地线"似的符号(图2). 图1 图2 连接后,会弹出如下窗体(图3),左侧界面选择信号,如下图中选择"clicked()"代表点击按钮触发右侧对应槽的操作. 勾选下

  • Python深度学习实战PyQt5信号与槽的连接

    目录 1. 信号与槽(Signals and slots) 1.1 信号与槽的原理 1.2 信号发送者与槽的接收者 2. QtDesigner 建立信号与槽的连接 2.1 信号与槽的连接:不同的发送者与接收者,槽函数为控件的内置函数 QtDesigner 设置信号/槽的连接的操作步骤如下: 2.2 信号与槽的连接:不同的发送者与接收者,槽函数为自定义函数 QtDesigner 设置信号/槽的连接的操作步骤如下: 2.3 信号与槽的连接:相同的发送者与接收者,槽函数为控件的内置函数 2.4 信号与

  • Python PyQt5学习之自定义信号

    PyQ5已经自动定义了很多QT自建的信号.但是在实际的使用中为了灵活使用信号与槽机制,可以根据需要自定义信号.通过使用pyqtSignal()方法定义新的信号,新的信号作为类的属性. 自定义signal说明: 新的信号应该定义在QObject的子类中.新的信号必须作为定义类的一部分,不允许将信号作为类的属性在类定义之后通过动态的方式进行添加.通过这种方式新的信号才能自动的添加到QMetaObject类中.这就意味这新定义的信号将会出现在Qt Designer,并且可以通过QMetaObject

  • Python PyQt5学习之样式设置详解

    目录 为标签添加背景图片 为按钮添加背景图片 缩放图片 设置窗口透明 为标签添加背景图片 import sys from PyQt5.QtGui import * from PyQt5.QtCore import * from PyQt5.QtWidgets import * if __name__ == "__main__": app = QApplication(sys.argv) win = QMainWindow() label = QLabel() label.setTool

  • python PyQt5(自定义)信号与槽使用及说明

    目录 1 定义信号 2 定义槽函数 3 连接信号与槽函数 4 发射信号 5 实例 自定义参数的传递及实例 lamdba表达式 实例 总结 所谓PyQt5高级自定义信号与槽,指的就是我们可以以自己喜欢的方式定义信号与槽函数,并传递参数,自定义信号的一般流程如下 定义信号 定义槽函数 连接信号与槽函数 发射信号 1 定义信号 PyQt5通过类成员变量定义信号对象 from PyQt5.QtCore import pyqtSignal # 无参数的信号 signal1 = pyqtSignal() #

  • Python深度学习实战PyQt5基本控件使用解析

    目录 1. PyQt5 控件简介 1.1 什么是控件 1.2 编辑控件的属性 1.3 PyQt5 的控件类型 输入控件: 显示控件: 高级控件: 2. 按钮控件 2.1 按钮控件简介 2.2 按键按钮(QPushButton) 2.3 其它按钮 3. 输入控件 3.1 输入控件简介 3.2 文本输入控件 3.3 调节输入控件 4. Python 应用程序调用图形界面 1. PyQt5 控件简介 1.1 什么是控件 控件也称控件对象,是 Qt用户界面上最基本的组件类型,也是构成用户界面的基本结构.

  • pyqt5自定义信号实例解析

    本文研究的主要是pyqt5自定义信号实例解析的相关内容,具体介绍如下. PyQt5已经自动定义了很多QT内建的信号.但是在实际的使用中为了灵活使用信号与槽机制,我们可以根据需要自定义signal.可以使用pyqtSignal()方法定义新的信号,新的信号作为类的属性. 自定义signal说明: pyqtSignal()方法原型(PyQt官网的定义): PyQt5.QtCore.pyqtSignal(types[, name[, revision=0[, arguments=[]]]]) Crea

  • Python深度学习实战PyQt5菜单和工具栏功能作用

    目录 1. 创建主窗口 1.1 窗口类型 1.2 编辑窗口的属性 1.3 图形界面设计的预览 2. 建立菜单栏 2.1 建立一级菜单 2.2 建立二级菜单 2.3 关联动作 3. 建立工具栏 3.1 添加工具栏 3.2 添加和编辑动作对象 3.3 向工具栏添加动作对象 4. 编写 Python 应用程序调用图形界面 1. 创建主窗口 上文中我们建立的图形界面程序 GUIdemo2.py,通过导入图形界面 uiDemo1.py,已经实现了主窗口的创建. 1.1 窗口类型 进一步地,在 QtDesi

  • Python深度学习实战PyQt5布局管理项目示例详解

    目录 1. 从绝对定位到布局管理 1.1 什么是布局管理 1.2 Qt 中的布局管理方法 2. 水平布局(Horizontal Layout) 3. 垂直布局(Vertical Layout) 4. 栅格布局(Grid Layout) 5. 表格布局(Form Layout) 6. 嵌套布局 7. 容器布局 布局管理就是管理图形窗口中各个部件的位置和排列.图形窗口中的大量部件也需要通过布局管理,对部件进行整理分组.排列定位,才能使界面整齐有序.美观大方. 1. 从绝对定位到布局管理 1.1 什么

随机推荐