Python Qt GUI设计:信号与槽的使用方法(基础篇—7)

简介: Python Qt GUI设计:信号与槽的使用方法(基础篇—7)

目录

1、信号与槽的概念


2、信号与槽的基础函数


2.1、创建信号函数


2.2、连接信号函数


2.3、断开信号函数


2.4、发射信号函数


3、信号和槽的使用方法


3.1、内置信号与槽的使用


3.2、自定义信号与槽的使用


3.2.1、定义信号


3.2.2、定义槽函数


3.2.3、连接信号与槽函数


3.2.4、发射信号


3.2.5、实例


1、信号与槽的概念

信号(signal)和槽(slot)是Qt的核心机制,也是在PyQt编程中对象之间进行通信的机制。在创建事件循环之后,通过建立信号和槽的连接就可以实现对象之间的通信。当信号发射(emit)时,连接的槽函数将会自动执行。


信号(signal)是在特定情况下被发射(emit)的一种通告。GUI程序设计的主要内容就是对界面上各组件发射的特定信号进行响应,只需要知道什么情况下发射了哪些信号,然后合理地去响应和处理这些信号就可以了。


槽(slot)实质上是一个函数,可以被直接调用,是对信号响应的函数。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数会被自动执行。


在Qt编程中,通过Qt信号和槽机制对鼠标或键盘在界面上的操作进行响应处理。例如,对鼠标单击按钮的执行处理信号的操作。


PyQt的窗口控件类中有很多内置信号,开发者也可以添加自定义信号。信号与槽具有如下特点:


一个信号可以连接多个槽;

一个信号可以连接另一个信号;

信号参数可以是任何Python类型;

一个槽可以监听多个信号;

信号与槽的连接方式可以是同步连接,也可以是异步连接;

信号与槽的连接可能会跨线程;

信号可能会断开。

2、信号与槽的基础函数

2.1、创建信号函数

本文仅描述主要的信号函数,具体详情可参照官方文档:Support for Signals and Slots — PyQt v5.15 Reference Guide


PyQt的内置信号是自动定义的。使用 PyQt5.QtCore.pyqtSignal()函数可以为QObject创建一个信号,使用pyqtSingnal()函数可以把信号定义为类的属性。pyqtSignal()函数信息如下图所以:


image.png


2.2、连接信号函数

使用connect()函数可以把信号绑定到槽函数上。connect()函数信息如下图所示:


image.png


2.3、断开信号函数

使用disconnect()函数可以解除信号与槽函数的绑定。disconnect()函数信息如下图所示:


image.png


2.4、发射信号函数

使用emit()函数可以发射信号。emit()函数信息如下图所示:


image.png


3、信号和槽的使用方法

信号与槽有三种使用方法,第一种是内置信号与槽的使用,第二种是自定义信号与槽的使用,第三种是装饰器的信号与槽的使用。由于第三种方法本质上是第一种方法的衍生,因此这里简要介绍前两种方法的使用。


Qt Designer中提供了一些最基础的信号和槽设置方法,在实际的项目开发中,信号和槽最佳的使用方式是Qt Designer和编程相结合,才能提高开发效率。


3.1、内置信号与槽的使用

所谓内置信号与槽的使用,是指在发射信号时,使用窗口控件的函数,而不是自定义的函数。在信号与槽中,可以通过 QObject.signal.connect将一个QObject的信号连接到另一个QObject的槽函数。


可以在【编辑->Edit Signal/slot】中进行信号和槽设置。


image.png


进入信号槽编辑模式,可以直接在发射者(“Button"按钮)上按住鼠标左键不放,拖动到接收者(Form窗体)上,这样就建立起了连接,如下图所示:


image.png


接着会弹出“配置连接"对话框,如下图所示:


image.png


可以看到按钮控件会发射很多内置信号和槽,选择所需信号,然后单击“OK"按钮,就会生成对应的槽函数处理。


例如,我想实现单击按钮关闭窗口的效果,所以这里勾选“显示从QWidget继承的信号和槽"复选框。


在左侧按钮的信号栏里选择clicked()信号,在右侧的Form槽函数中选择close(),这意味着对按钮单击会发射clicked信号,这个信号会被Form窗体的槽函数close()捕捉到,并触发该窗体的close行为(也就是关闭该窗体)。


连接信号和槽成功后,会发现在Edit Signal/slot(编辑信号/槽)模式下,所创建的信号和槽关系的连线是红色的,如下图所示:


image.png


接着将UI界面转换为Python文件,这里我使用Eric 6编译,不再赘述,效果如下所示:


image.png


拓展学习:Python Qt GUI设计:将UI文件转换为Python文件的三种妙招(基础篇—2)


UI文件编译后代码如下所示:


from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(383, 276)
        self.pushButton = QtWidgets.QPushButton(Form)
        self.pushButton.setGeometry(QtCore.QRect(140, 120, 93, 28))
        self.pushButton.setObjectName("pushButton")
        self.retranslateUi(Form)
        self.pushButton.clicked.connect(Form.close)
        QtCore.QMetaObject.connectSlotsByName(Form)
    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.pushButton.setText(_translate("Form", "Button"))
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Form = QtWidgets.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

代码中,通过connect函数连接按钮的clicked()信号和槽函数Form.close(),如下所示:


self.pushButton.clicked.connect(Form.close)

运行程序,按钮是信号发射者,当单击按钮之后会发射一个信号,通过这行代码程序内部的通信机制知道这个按钮的单击事件被连接到窗体的关闭事件上,然后通知接收者窗体,可以运行槽函数close(),实现窗口关闭。


image.png


3.2、自定义信号与槽的使用

自定义信号与槽是指在发射信号时,不使用窗口控件的函数,而是使用自定义的函数(简单地说,就是使用pyqtSignal类实例发射信号)。


之所以要使用自定义信号与槽,是因为通过内置函数发射信号有自身的缺陷,主要是以下三点:


内置函数只包含一些常用的信号,有些信号的发射找不到对应的内置函数;

内置函数只有在特定情况下(如按钮的点击事件)才能发射这种信号;

内置函数传递的参数是特定的,不可以自定义。使用自定义的信号函数则没有这些缺陷。

在PyQt5编程中,自定义信号与槽的适用范围很灵活。例如,因为业务需求,在程序中的某个地方需要发射一个信号,传递多种数据类型(实际上就是传递参数),然后在槽函数中接收传递过来的数据,这样就可以非常灵活地实现一些业务逻辑。


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


定义信号

定义槽函数

连接信号与槽函数

发射信号

3.2.1、定义信号

使用pyqtSingnal()函数可以把信号定义为类的属性,示例代码如下所示:

#无参数的信号
  signal1=pyqtSignal()
  #带一个参数(整数)的信号
  signal2=pyqtSignal(int)
  #带两个参数(整数,字符串)的信号
  signal3=pyqtSignal(int,str)
  #带一个参数(列表)的信号
  signal4=pyqtSignal(list)
  #带一个参数(字典)的信号
  signal5=pyqtSignal(dict)
  #带(整数 字符串)或者(字符串)的信号
  signal6=pyqtSignal([int,str],[str])

3.2.2、定义槽函数

定义一个槽函数,它有多个不同的输入参输数,示例代码如下所示:


def signalCall1( self ):
    print("signal1 emit")
  def signalCall2( self,val ):
    print('signal2 emit,value:',val)
  def signalCall3( self,val,text ):
    print('signall3 emit,value:',val,text)
  def signalCall4( self,val ):
    print('signal4 emit,value:',val)
  def signalCall5( self,val ):
    print('signal5 emit,value',val)
  def signalCall6( self,val,text ):
    print('signal6 emit,value',val,text)
  def signalCall7( self,val ):
    print('signal6 ovetload emit',val)

3.2.3、连接信号与槽函数

使用connect()函数可以把信号绑定到槽函数上,示例代码如下所示:


#信号与槽函数的链接
    self.signal1.connect(self.signalCall1)
    self.signal2.connect(self.signalCall2)
    self.signal3.connect(self.signalCall3)
    self.signal4.connect(self.signalCall4)
    self.signal5.connect(self.signalCall5)
    self.signal6[int,str].connect(self.signalCall6)
    self.signal6[str].connect(self.signalCall7)

3.2.4、发射信号

使用emit()函数可以发射信号,示例代码如下所示:


 

#信号发射
    self.signal1.emit()
    self.signal2.emit(1)
    self.signal3.emit(1,'第三个')
    self.signal4.emit([1,2,3,4])
    self.signal5.emit({"name":'JIA','age':'21'})
    self.signal6[int,str].emit(1,"第六")
    self.signal6[str].emit('第六')

3.2.5、实例

将上述片段代码,整合,非常简单,各位可以看着理解。

from PyQt5.QtCore import QObject,pyqtSignal
class CusSignal(QObject):
  #无参数的信号
  signal1=pyqtSignal()
  #带一个参数(整数)的信号
  signal2=pyqtSignal(int)
  #带两个参数(整数,字符串)的信号
  signal3=pyqtSignal(int,str)
  #带一个参数(列表)的信号
  signal4=pyqtSignal(list)
  #带一个参数(字典)的信号
  signal5=pyqtSignal(dict)
  #带(整数 字符串)或者(字符串)的信号
  signal6=pyqtSignal([int,str],[str])
  def __init__(self,parent=None):
    super(CusSignal, self).__init__(parent)
    #信号与槽函数的链接
    self.signal1.connect(self.signalCall1)
    self.signal2.connect(self.signalCall2)
    self.signal3.connect(self.signalCall3)
    self.signal4.connect(self.signalCall4)
    self.signal5.connect(self.signalCall5)
    self.signal6[int,str].connect(self.signalCall6)
    self.signal6[str].connect(self.signalCall7)
    #信号发射
    self.signal1.emit()
    self.signal2.emit(1)
    self.signal3.emit(1,'第三个')
    self.signal4.emit([1,2,3,4])
    self.signal5.emit({"name":'JIA','age':'21'})
    self.signal6[int,str].emit(1,"第六")
    self.signal6[str].emit('第六')
  #槽函数
  def signalCall1( self ):
    print("signal1 emit")
  def signalCall2( self,val ):
    print('signal2 emit,value:',val)
  def signalCall3( self,val,text ):
    print('signall3 emit,value:',val,text)
  def signalCall4( self,val ):
    print('signal4 emit,value:',val)
  def signalCall5( self,val ):
    print('signal5 emit,value',val)
  def signalCall6( self,val,text ):
    print('signal6 emit,value',val,text)
  def signalCall7( self,val ):
    print('signal6 ovetload emit',val)
if __name__ == '__main__':
  custSignal=CusSignal()

运行效果如下所示:


image.png


关于信号与槽的使用方法就讲到这了,在后面的实践中我们再细聊,感兴趣小伙伴可看看以下的拓展学习链接~


相关文章
|
5月前
|
编译器
(9)Qt中信号与槽重载的解决方案
本文介绍了在Qt中处理信号与槽重载问题的三种解决方案:使用函数指针、Qt提供的QOverload类和Qt4的宏方式。
240 3
|
4月前
|
测试技术 开发者 Python
Python(GUI)之活动积分记录表
本文介绍了一套使用Python的Tkinter库构建的学生活动积分记录系统。该系统允许教师选择班级和学生,输入加分分数及原因,并将数据保存至文件,旨在简化学生积分管理流程,提升教学效率。
80 6
|
5月前
(8)Qt中的自定义信号
本文介绍了如何在Qt框架中创建和使用自定义信号,并通过一个父子窗口切换的示例来展示自定义信号的实现和应用。
189 3
|
3月前
|
传感器 安全
第四问:QT中信号和槽原理
Qt的信号与槽机制是观察者模式的典型实现,允许对象间通信而不直接依赖。信号用于通知事件发生,槽是响应信号的函数,通过`QObject::connect()`连接。这种机制实现了松耦合、灵活扩展和自动通知,适用于UI更新和数据绑定等场景。
113 1
|
4月前
|
C++
003 Qt_信号和槽-上
本文介绍了Qt中的信号与槽机制,包括信号和槽的概念、本质及连接方法,并演示了如何自定义槽函数。信号是事件的体现,槽是对信号的响应函数。通过信号与槽,可以将独立的控件关联起来,实现复杂的交互逻辑。文中还详细展示了如何在Qt项目中定义和使用槽函数,通过实例代码和图形化界面操作,帮助读者更好地理解和应用这一机制。
102 1
003 Qt_信号和槽-上
|
4月前
|
数据可视化 开发者 Python
Python GUI开发:Tkinter与PyQt的实战应用与对比分析
【10月更文挑战第26天】本文介绍了Python中两种常用的GUI工具包——Tkinter和PyQt。Tkinter内置于Python标准库,适合初学者快速上手,提供基本的GUI组件和方法。PyQt基于Qt库,功能强大且灵活,适用于创建复杂的GUI应用程序。通过实战示例和对比分析,帮助开发者选择合适的工具包以满足项目需求。
304 7
|
5月前
|
Linux Android开发 开发者
【Python】GUI:Kivy库环境安装与示例
这篇文章介绍了 Kivy 库的安装与使用示例。Kivy 是一个开源的 Python 库,支持多平台开发,适用于多点触控应用。文章详细说明了 Kivy 的主要特点、环境安装方法,并提供了两个示例:一个简单的 Hello World 应用和一个 BMI 计算器界面。
189 0
|
5月前
|
机器学习/深度学习 算法框架/工具 Python
基于深度学习的手写数字识别项目GUI(Deep Learning Project – Handwritten Digit Recognition using Python)
基于深度学习的手写数字识别项目GUI(Deep Learning Project – Handwritten Digit Recognition using Python)
160 0
|
7月前
|
前端开发 JavaScript 测试技术
Python中的GUI测试
【8月更文挑战第15天】本文探讨了Python中图形用户界面(GUI)测试的关键工具——Selenium与PyQt。Selenium专为Web应用测试设计,能模拟用户行为如点击和输入文本。PyQt则基于Qt框架,用于构建丰富的桌面应用程序及编写自动化测试脚本。
64 3
|
7月前
|
API 开发工具 C语言
C语言与图形界面:利用GTK+、Qt等库创建GUI应用。
C语言与图形界面:利用GTK+、Qt等库创建GUI应用。
453 0

热门文章

最新文章