我的编程空间,编程开发者的网络收藏夹
学习永远不晚

PyQt5信号与槽机制案例详解

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

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

PyQt5信号与槽机制案例详解

信号和槽机制是 QT 的核心机制,要精通 QT 编程就必须对信号和槽有所了解。信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性,也是 QT 区别于其它工具包的重要地方。

信号和槽是用来在对象间传递数据的方法:当一个特定事件发生的时候,信号会被发射出来,槽调用是用来响应相应的信号的。Qt中对象已经包含了许多预定义的信号(基本组件都有各自特有的预定义的信号),根据使用的场景也可以添加新的信号。同样Qt的对象中已经包含了许多预定义的槽函数,但也可以根据使用的场景添加新的槽函数。

一、概念简介

所有继承qwidget的控件都支持信号与槽机制。

信号:当一个信号发生改变时,向外界发出的信息。

当一个信号被发射的时候,与其关联的槽函数被立刻执行。其中该对象只负责发送信号,发射该信号的对象并不知道是那个对象在接收这个信号。这样保证了对象与对象之间的低耦合。
如果存在信号和多个槽函数相关联的时候,当信号被发射时,这些槽的执行顺序将会是随机的、不确定的。

槽:一个执行某些操作的函数或者方法。

当和槽连接的信号被发射时,槽会被调用。一个槽并不知道是否有任何信号与自己相连接。

信号与槽机制:主要分两种

手动操作:信号连接槽

自动操作:当信号发出时,连续的槽函数会自动执行

信号连接

通过调用 QObject 对象的 connect 函数来将某个对象的信号与另外一个对象的槽函数相关联,这样当发射者发射信号时,接收者的槽函数将被调用。该函数的定义如下:

object.信号.connet(槽函数)

当信号与槽没有必要继续保持关联时,可以使用 disconnect 函数来断开连接。其定义如下:

disconnect(槽函数)

信号和槽的特点:

1.一个信号可以连接到多个槽:当信号发出后,槽函数都会被调用,但是调用的顺序是随机的,不确定的。

2.多个信号可以连接到同一个槽:其中任何一个信号发出,槽函数都会被执行。

3.信号的参数可以是任何的Python类型,如list,dict等python独有的类型。自定义信号的时候举例说明。

4.信号和槽的连接可以被移除:比如断开某个特定信号的关联。

5.信号可以和另外一个信号进行关联:第一个信号发出后,第二个信号也同时发送。比如关闭系统的信号发出之后,同时会发出保存数据的信号。

二、代码样例

整体代码如下:

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QWidget, QLCDNumber, QSlider,QGridLayout,QLabel,QHBoxLayout, QGroupBox,
    QVBoxLayout, QApplication,QProgressBar,QPushButton,QMessageBox)
 
class SignalSlot(QWidget):
    def __init__(self):
        super(SignalSlot,self).__init__()      
        self.initUI()
    def initUI(self):
        self.controlsGroup = QGroupBox("运行样本")
        self.lcdNumber = QLCDNumber(self)
        self.slider = QSlider(Qt.Horizontal, self)
        self.pBar = QProgressBar(self)
        vbox = QVBoxLayout()
        vbox.addWidget(self.pBar)
        vbox.addWidget(self.lcdNumber)
        vbox.addWidget(self.slider)
        self.controlsGroup.setLayout(vbox)
        controlsLayout = QGridLayout()
        self.label1 = QLabel("保存状态:")
        self.saveLabel = QLabel()
        self.label2 = QLabel("运行状态:")
        self.runLabel = QLabel()
        self.buttonSave = QPushButton("保存")
        self.buttonRun = QPushButton("运行")
        self.buttonStop = QPushButton("停止")
        self.buttonDisconnect = QPushButton("解除关联")
        self.buttonConnect = QPushButton("绑定关联")
        controlsLayout.addWidget(self.label1,0,0)
        controlsLayout.addWidget(self.saveLabel,0,1)
        controlsLayout.addWidget(self.label2,1,0)
        controlsLayout.addWidget(self.runLabel,1,1)
        controlsLayout.addWidget(self.buttonSave,2,0)
        controlsLayout.addWidget(self.buttonRun,2,1)
        controlsLayout.addWidget(self.buttonStop,2,2)
        controlsLayout.addWidget(self.buttonDisconnect,3,0)
        controlsLayout.addWidget(self.buttonConnect,3,1)
        layout = QHBoxLayout()
        layout.addWidget(self.controlsGroup)
        layout.addLayout(controlsLayout)
        self.setLayout(layout)
        self.buttonRun.clicked.connect(self.buttonSave.clicked)
        self.slider.valueChanged.connect(self.pBar.setValue)
        self.slider.valueChanged.connect(self.lcdNumber.display)
        self.buttonSave.clicked.connect(self.showMessage)
        self.buttonRun.clicked.connect(self.showMessage)
        self.buttonDisconnect.clicked.connect(self.unbindConnection)
        self.buttonConnect.clicked.connect(self.bindConnection)
        self.buttonStop.clicked.connect(self.stop)
        self.setGeometry(300, 500, 500, 180)
        self.setWindowTitle('信号和槽')
    def showMessage(self):
        if self.sender().text() == "保存":
            self.saveLabel.setText("Saved")
        elif self.sender().text() == "运行":
            self.runLabel.setText("Running")
    def unbindConnection(self):
        self.slider.valueChanged.disconnect()
    def bindConnection(self):
    def stop(self):
        self.saveLabel.setText("")
        self.runLabel.setText("")
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = SignalSlot()
    ex.show()
    sys.exit(app.exec_())

控件说明:

控件类型控件名称作用
controlsGroupQGroupBox为构建分组框提供了支持。分组框通常带有一个边框和一个标题栏,作为容器部件来使用,在其中可以布置各种窗口部件。
lcdNumberQLCDNumber用于显示一个带有类似液晶显示屏效果的数字。
sliderQSlider提供一个垂直或者水平的滑动条,滑动条是一个用于控制有界值典型的控件,它允许用户沿水平或者垂直方向在某一范围内移动滑块,并将滑块所在的位置转换为一个合法范围内的整数值
pBarQProgressBar提供了一个水平或垂直的进度条
label1QLabel
  • 占位符
  • 显示文本
  • 显示图片
  • 放置gif动画
  • 超链接
  • 提示标记
buttonSaveQPushButton常用的按钮控件

界面说明: 

程序样本运行的界面逻辑,先设定运行的程序样本数量,然后先保存后运行的逻辑状态。通过slider的滑动来改变progressBar和LCD的显示数据;“保存”按钮保存运行的样本;“运行”按钮运行程序样本;“解除关联”解除slider.valueChanged信号的绑定,此时slider的滑动,不会改变progressBar和LCD的显示。

self.controlsGroup = QGroupBox("运行样本")
self.lcdNumber = QLCDNumber(self)
self.slider = QSlider(Qt.Horizontal, self)
self.pBar = QProgressBar(self)
vbox = QVBoxLayout()
vbox.addWidget(self.pBar)
vbox.addWidget(self.lcdNumber)
vbox.addWidget(self.slider)
self.controlsGroup.setLayout(vbox)

实例化一个QGroupBox,在其中添加QProgressBar、QLCDNumber、QSlider控件。

controlsLayout = QGridLayout()
self.label1 = QLabel("保存状态:")
self.saveLabel = QLabel()
self.label2 = QLabel("运行状态:")
self.runLabel = QLabel()
self.buttonSave = QPushButton("保存")
self.buttonRun = QPushButton("运行")
self.buttonStop = QPushButton("停止")
self.buttonDisconnect = QPushButton("解除关联")
self.buttonConnect = QPushButton("绑定关联")
 
controlsLayout.addWidget(self.label1,0,0)
controlsLayout.addWidget(self.saveLabel,0,1)
controlsLayout.addWidget(self.label2,1,0)
controlsLayout.addWidget(self.runLabel,1,1)
controlsLayout.addWidget(self.buttonSave,2,0)
controlsLayout.addWidget(self.buttonRun,2,1)
controlsLayout.addWidget(self.buttonStop,2,2)
controlsLayout.addWidget(self.buttonDisconnect,3,0)
controlsLayout.addWidget(self.buttonConnect,3,1)

通过QGridLayout()添加标签以及按钮。

layout = QHBoxLayout()
layout.addWidget(self.controlsGroup)
layout.addLayout(controlsLayout)
self.setLayout(layout)

 最后通过QHBoxLayout将左右两个界面合并,形成最终界面。

信号与槽说明:

signal和slot进行绑定。
1.一个信号绑定多个槽:

self.slider.valueChanged.connect(self.pBar.setValue)
self.slider.valueChanged.connect(self.lcdNumber.display)

slider控件的valueChanged信号,同时与QProgressBar的setValue(),QLCDNumber的display()槽函数绑定,当valueChanged信号触发的时候,这两个槽函数均会被调用。

2.多个信号绑定到一个槽:

self.buttonSave.clicked.connect(self.showMessage)
self.buttonRun.clicked.connect(self.showMessage)

buttonSave和buttonRun这两个对象的clicked信号,同时绑定到showMessage()这个槽函数。无论哪一个信号被触发,showMessage()这个槽函数均会被调用,而根据self.sender().text() 这个函数来判断显示的不同内容。

3.信号和槽的连接可以被移除:

self.buttonDisconnect.clicked.connect(self.unbindConnection)

当buttonDisconnect信号触发之后,与其关联的槽函数unbindConnection()中就会执行disconnect()方法,如下:

def unbindConnection(self):
        self.slider.valueChanged.disconnect()

其中执行disconnect()的时候可以指定解除与某个特定的slot槽的关联,比如self.slider.valueChanged.disconnect(self.pBar.setValue),此时解除和QProgressBar的setValue()的关联,如果不指定,将解除和这个信号所有关联的槽。

4、信号与信号的关联:

self.buttonRun.clicked.connect(self.buttonSave.clicked)

在样例说明中提到,在运行之前要对样本进行保存,所以为了保证运行的时候执行了保存的操作,所以将buttonRun.clicked信号和buttonSave.clicked信号关联起来。

示例中在没有执行“保存”(buttonSave)的时候,执行“运行”(buttonRun),此时由于两个对象的clicked信号已经关联,所以buttonSave的clicked同样会执行。

最终结果:

本文是《从零开始学PyQt5》第五篇,希望小伙伴们可以多多支持,一起学习!

参考:

Pyqt5系列(七)-信号与槽机制_追逐阳光的风-CSDN博客_pyqt5信号和槽

到此这篇关于PyQt5信号与槽机制案例详解的文章就介绍到这了,更多相关PyQt5信号与槽机制内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

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

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

PyQt5信号与槽机制案例详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

qt信号与槽机制的原理是什么

Qt的信号与槽(Signals and Slots)机制是Qt的一个重要特性,用于处理对象之间的事件通信。它的原理基于C++的特性和Qt的元对象系统。在使用信号与槽机制前,首先需要定义一个信号和一个槽。信号是一个声明,它是一个在特定事件发生
2023-09-27

Django的信号机制详解

Django提供一种信号机制。其实就是观察者模式,又叫发布-订阅(Publish/Subscribe) 。当发生一些动作的时候,发出信号,然后监听了这个信号的函数就会执行。 Django内置了一些信号,比如:django.db.models
2022-06-04

微信小程序的运行机制与安全机制解决方案详解

这篇文章主要介绍了微信小程序的运行机制与安全机制解决方案,接触小程序有一段时间了,总得来说小程序开发门槛比较低,但其中基本的运行机制和原理还是要懂的
2023-02-09

Flutter与WebView通信方案示例详解

这篇文章主要为大家介绍了Flutter与WebView通信方案示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-04

详解Python的Flask框架中的signals信号机制

Flask 提供了信号(Signals)功能,是一种消息分发机制。类似于钩子(Hooks)。使用信号功能可以降低程序的耦合,分解复杂的业务模型。例如在更新了产品数据后,可以发送一个信号。当有需要对产品数据进行处理的功能时,就可以捕获信号进行
2022-06-04

kotlin实现快递与号码归属地查询案例详解

时间轴时一个很炫酷的效果,一般作用在物流信息上,我们同样也可以作为一个学习对象去学习他的使用方法,同时呢,我们可以在线查询我们的电话号码归属地,巧用键盘的逻辑提升我们用户体验
2023-02-16

MySQL基础篇(06):事务管理,锁机制案例详解

本文源码:GitHub·点这里 || GitEE·点这里一、锁概念简介1、基础描述锁机制核心功能是用来协调多个会话中多线程并发访问相同资源时,资源的占用问题。锁机制是一个非常大的模块,贯彻MySQL的几大核心难点模块:索引,锁机制,事务。这里是基于MySQL5
MySQL基础篇(06):事务管理,锁机制案例详解
2018-06-26

详解Qt中的双缓冲机制与实例应用

所谓双缓冲机制,是指在绘制控件时,首先将要绘制的内容绘制在一个图片中,再将图片一次性地绘制到控件上。本文主要为大家介绍了Qt中的双缓冲机制与实例应用,希望对大家有所帮助
2023-03-11

详解java中的互斥锁信号量和多线程等待机制

互斥锁和信号量都是操作系统中为并发编程设计基本概念,互斥锁和信号量的概念上的不同在于,对于同一个资源,互斥锁只有0和1 的概念,而信号量不止于此。也就是说,信号量可以使资源同时被多个线程访问,而互斥锁同时只能被一个线程访问互斥锁在java中
2023-05-31

SpringBoot + WebSocket如何实现答题对战匹配机制案例详解

小编给大家分享一下SpringBoot + WebSocket如何实现答题对战匹配机制案例详解,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!概要设计类似竞技问答游戏:用户随机匹配一名对手,双方同时开始答题,直到双方都完成答
2023-06-15

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录