第15.19节 PyQt(Python+Qt)入门学习:自定义信号与槽链接

1、引言

本文利用中介绍了PyQt中的信号和槽机制,除了使用PyQt组件的已有信号外,PyQt和Qt同样支持自定义信号。本节将介绍自定义信号及其余信号、槽的高级特性。css

2、自定义信号的简单例子

2.一、案例说明

在一个图形界面类中类变量内定义一个信号selfSig,在类的实例方法中定义一个方法sigRecv做为槽函数接收信号、在构造方法中完成信号和槽的链接。html

为了发送信号,在图形界面中有个名为emitSig的信号发送按钮,在Designer中进行了按钮的clicked信号和槽函数emitSigStart的关联。当按下按钮时,将按钮后面输入行中的内容发送出去,emitSigStart槽函数则将接收到的内容在显示窗w_displayInf中显示。python

案例的主程序名为sigApp.py,图形界面文件为:ui_mainWin.ui,图形界面生成的代码为ui_mainWin.py,图形界面生成代码的类名为:Ui_w_mainWin。zaipycharm的工程文件截图:
在这里插入图片描述web

2.二、案例运行截图

在这里插入图片描述

2.三、案例主程序代码

# -*- coding: utf-8 -*-

import sys
from PyQt5 import QtWidgets,QtCore,QtGui
import ui_mainWin

class w_mainWin(ui_mainWin.Ui_w_mainWin,QtWidgets.QWidget):
    selfSig = QtCore.pyqtSignal(str) #定义信号,带一个str类型的参数

    def __init__(self): #构造方法
        super(w_mainWin, self).__init__()
        self.setupUi(self)
        self.selfSig[str].connect(self.sigRecv) #链接信号和槽

    def emitSigStart(self): #图形界面按钮clicked信号的槽函数
        info = self.sigInfo.text()
        self.selfSig[str].emit(info)

    def sigRecv(self,info): #接收信号的槽函数
        self.w_displayInf.append(f"Received sinal:{info}")

3、自定义信号的案例详解

上面介绍的案例,是一个类内的信号和槽函数绑定,若是要实现相似功能,彻底无需经过自定义信号和槽的机制来实现,直接点击按钮将输入行内文本添加到显示窗就能够,但经过这个案例能够比较清楚的知道PyQt中自定义信号及使用的过程,当信号和槽不在一个对象时相关步骤及方法是同样的,只是链接时的对象名不一样,没有本质区别。app

3.一、定义信号

3.1.一、语法

定义信号的本质就是在类体中使用QtCore.pyqtSignal定义一个类变量,QtCore.pyqtSignal的完整语法以下:svg

PyQt5.QtCore.pyqtSignal(types[, name[, revision=0[, arguments=[]]]])

上面案例的信号定义在类开始处:函数

selfSig = QtCore.pyqtSignal(str) #定义信号,带一个str类型的参数

3.1.二、参数释义

  • types :定义信号的C++签名(函数签名由参数个数与其类型组成。函数在重载时,利用函数签名的不一样即参数个数与类型的不一样来区别调用者到底调用的是那个方法)的类型。每种类型均可以是Python类型对象,也能够是一个C++类型的字符串,或者,每个均可以是一个序列(如列表)类型参数,在这种状况下,每一个序列定义不一样信号重载的签名,即同一个信号名有不一样签名(即信号名相同、签名不一样的重载信号),每一个签名是一序列类型,第一个序列将是重载缺省签名。学习

  • name:信号名字,若是信号名就是类变量名则能够省略该参数,因为types参数是可变的,所以本参数使用必须经过关键字参数方式传值,即name=‘信号名’方式ui

  • revision、arguments:都是关键字参数,用于输出到QML使用,QML是Qt使用的一种相似css和js功能叠加的脚本语言,老猿没准备学习和介绍,所以这两个参数在此就不关注了。.net

3.1.三、返回值

pyqtSignal定义返回的就是一个信号,但这时的信号与普通的类变量差很少,并无信号相关的方法。以上例为例,在信号定义返回后调试模式下观察selfSig这个变量的状况,如图(由于是类变量,因此必须带类名观察):
在这里插入图片描述

3.二、信号与槽的链接

3.2.一、语法

自定义信号与槽的链接与PyQt内部定义信号与槽的链接本质上是同样的,都是调用信号的connect方法,相关方法语法以下:
connect(slot[, type=PyQt5.QtCore.Qt.AutoConnection[, no_receiver_check=False]])

上面案例中的链接语句在构造方法内,以下:

self.selfSig[str].connect(self.sigRecv) #链接信号和槽

3.2.二、参数释义

  • slot:信号须要链接的槽,能够是一个与信号匹配的某个对象的回调方法、也能够是一个已经绑定的有相同签名的其余信号
  • type:链接的类型,其类型为枚举类型Qt.ConnectionType,有以下种取值: 在这里插入图片描述
  • no_receiver_check:若是为True,禁止检查下层的C++接收对象实例是否还存在,无论怎样都要发出信号,默认值为False。

3.2.三、返回值

connect调用后,若是正常返回,则返回对象为一个 Connection对象,这个对象在 当要执行disconnect断开信号与槽的链接时使用,这是断开信号与一个lambda函数的链接的惟一方法。

3.三、发射信号

发射信号很是简单,就是调用信号的方法emit。语法以下:
emit(args)
参数args:传递给全部链接槽的可选参数序列。

上面案例的发射信号语句以下:

self.selfSig[str].emit(info)

4、小结

本节经过一个简单案例介绍了PyQt中怎么自定义一个信号、怎么链接一个信号,当信号定义好之后,就与Qt内置信号没有本质的区别,若是将信号所在对象经过相关方法定义成一个Qt Designer的插件时,信号就能在Designer中直接可见和操做。

更多关于信号和槽的内容请参考《 专栏:使用PyQt开发图形界面Python应用》中《第六章 信号和槽进阶–自定义信号及其余信号、槽的高级特性》的内容。

老猿Python,跟老猿学Python!