当前位置: 首页 > news >正文

QT信号和槽与自定义的信号和槽

QT信号和槽与自定义的信号和槽

1.概述

这篇文章介绍下QT信号和槽的入门知识,通过一个案例介绍如何创建信号和槽,并调用他们。

2.信号和槽使用

下面通过点击按钮关闭窗口的案例介绍如何使用信号和槽。

  1. 创建按钮
    在widget.cpp文件中创建按钮代码如下
#include "mywidget.h"
#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent)
{//    第二种创建按钮方式QPushButton *btn2 = new QPushButton("构造按钮",this);
  1. 使用信号和槽实现点击按钮关闭窗口
    使用QObject类中的connect函数连接信号和槽,该函数需要4个参数
    • 参数1: 发送者,谁发送信号——btn2
    • 参数2: 发送的是什么信号,信号用函数地址——&QPushButton::clicked
    • 参数3: 接受者,谁来接受信号——this指的是当前窗口对象
    • 参数4: 槽,接受者做出的动作——&QWidget::close
connect(btn2, &QPushButton::clicked, this, &QWidget::close);

3.如何查看QT提供的信号和槽函数
在使用connect连接信号和槽的时候,第一个参数发送者是btn2按钮对象,属于QPushButton类。

如何查看系统提供的信号?
第二个参数需要知道发送什么信号,这个时候怎么知道QPushButton提供了哪些信号那,这就需要查看QT帮助文档。
首先在编辑器中点击HELP 打开帮助文档,输入QPush查看QPushButton中提供的内容没有Signal 信号。
在这里插入图片描述
接着查看QPushButton父类
在这里插入图片描述
在父类中看到有Signals 信号,点击它,跳转到信号介绍位置。
在这里插入图片描述
在信号介绍中给出了所有的信号,我们选择第一个就是我们示例中的点击信号。在使用这个信号函数时候一定要用地址引用方式调用它,就是在调用前加上&符号。

connect(btn2, &QPushButton::clicked, this, &QWidget::close);

在这里插入图片描述

如何查看系统提供的槽?
查看方法和上面查看信号一样,我们是关闭窗口,窗口的类是QWidge ,查看它的槽中提供了close() 函数。

connect(btn2, &QPushButton::clicked, this, &QWidget::close);

在这里插入图片描述

3.自定义信号和槽功能

上面介绍的是使用QT提供的信号和槽,下面通过一个实例介绍如何自定义自己的信号和槽的功能。
示例功能描述

老师类发出一个下课的信号,学生类的槽执行请客吃饭

  1. 新建项目

首先新建一个QWidge类型项目,然后在项目名称上右键,新建clss文件,名称输入
Teacher 。然后再新建另一个class文件,名称输入Student
在这里插入图片描述
2. 创建信号
teacher.h文件中创建信号, 信号只需要定义不需要实现。

#ifndef TEACHER_H
#define TEACHER_H#include <QObject>class Teacher : public QObject
{Q_OBJECT
public:explicit Teacher(QObject *parent = nullptr);signals:/* 自定义信号,写到signals中* 返回值是void,只需要声明不需要实现* 可以有参数,可以重载*/void hungry();};#endif // TEACHER_H
  1. 创造槽
    student.h文件中创建槽函数,槽函数声明后需要在student.cpp文件中实现功能。
#ifndef STUDENT_H
#define STUDENT_H#include <QObject>class Student : public QObject
{Q_OBJECT
public:explicit Student(QObject *parent = nullptr);signals:public slots:/* 早起QT版本,必须写到public slots, 高级版本可以写到public或者全局中* 返回值void, 需要声明并且实现* 可以有参数,可以重载
*/void treat();};#endif // STUDENT_H

student.cpp文件中实现功能

#include "student.h"
#include <QDebug>Student::Student(QObject *parent) : QObject(parent)
{}void Student::treat()
{qDebug() << "执行槽函数,请客吃饭";
}
  1. 连接信号和槽
    QWidget.h 文件中创建Teacher和Student类对象,创建一个触发下课的函数。
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include "teacher.h"
#include "student.h"QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
//    创建Teacher和Student类对象Teacher *tc;Student *st;private:Ui::Widget *ui;
//    创建一个触发下课的函数void classIsDown();
};
#endif // WIDGET_H

QWidget.cpp 文件中实现信号和槽的功能

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//    1.创建对象this->tc = new Teacher(this);this->st = new Student(this);
//    2.连接信号和槽connect(tc, &Teacher::hungry, st, &Student::treat);
//    3.调用触发下课函数classIsDown();
}//4.下课函数使用emit发送信号
void Widget::classIsDown()
{emit tc->hungry();
}
Widget::~Widget()
{delete ui;
}

4.信号和槽函数重载

当我们自定义信号和槽函数时,他们可以通过参数进行重载,实现更多的功能。当使用重载时,调用的时候需要使用函数指针指向函数地址,确认调用哪个重载的函数。
继续使用上面的示例,在Teacher和Student类中添加重载的信号和槽

  1. 添加重载的信号
    在teacher.h文件中新增void hungry(QString foodName); 有参的信号
#ifndef TEACHER_H
#define TEACHER_H#include <QObject>class Teacher : public QObject
{Q_OBJECT
public:explicit Teacher(QObject *parent = nullptr);signals:/* 自定义信号,写到signals中* 返回值是void,只需要声明不需要实现* 可以有参数,可以重载*/void hungry();
//    信号参数重载void hungry(QString foodName);};#endif // TEACHER_H
  1. 添加重载的槽
    在student.h文件中添加void treat(QString foodName); 槽函数
#ifndef STUDENT_H
#define STUDENT_H#include <QObject>class Student : public QObject
{Q_OBJECT
public:explicit Student(QObject *parent = nullptr);signals:public slots:/* 早起QT版本,必须写到public slots, 高级版本可以写到public或者全局中* 返回值void, 需要声明并且实现* 可以有参数,可以重载
*/void treat();//    槽参数重载void treat(QString foodName);};#endif // STUDENT_H

在student.cpp文件中实现槽函数功能

#include "student.h"
#include <QDebug>Student::Student(QObject *parent) : QObject(parent)
{}void Student::treat()
{qDebug() << "执行槽函数,请客吃饭";
}void Student::treat(QString foodName)
{qDebug() << "执行参数重载的槽函数,吃" << foodName.toUtf8().data();
}
  1. 调用重载的信号和槽函数
    在widget.cpp文件中通过connect()函数调用信号和槽之前需要先指明调用的是有参的信号和槽函数,方法如下
//    调用有参的信号和槽
//    1.声明一个函数指针,指向函数地址void(Teacher::*teacherSignal) (QString) = &Teacher::hungry;void(Student::*studentSlot)(QString) = &Student::treat;
//    2.连接信号和槽connect(tc, teacherSignal, st, studentSlot);

完整代码

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//    1.创建对象this->tc = new Teacher(this);this->st = new Student(this);
//    2.连接信号和槽
//    connect(tc, &Teacher::hungry, st, &Student::treat);
//    3.调用触发下课函数
//    classIsDown();//    调用有参的信号和槽
//    1.声明一个函数指针,指向函数地址void(Teacher::*teacherSignal) (QString) = &Teacher::hungry;void(Student::*studentSlot)(QString) = &Student::treat;
//    2.连接信号和槽connect(tc, teacherSignal, st, studentSlot);
//    3.调用触发下课函数classIsDown();
}//4.下课函数使用emit发送信号
void Widget::classIsDown()
{
//    调用无参信号
//    emit tc->hungry();
//    调用有参信号emit tc->hungry("糖醋里脊");
}
Widget::~Widget()
{delete ui;
}

5.信号连接信号

上面触发信号使用的是emit,如果我们想实现通过点击按钮来触发信号,那么可以采用普通的按钮发送信号控制槽函数,还可以采用信号连接信号实现。

//    点击按钮触发下课,第一种方式通过信号和槽实现。QPushButton *btn = new QPushButton("下课",this);this->resize(600,400);
//    connect(btn, &QPushButton::clicked, this, &Widget::classIsDown);//    点击按钮触发下课,第二种通过信号连接信号实现void(Teacher::*teacherSignal2) (void) = &Teacher::hungry;void(Student::*studentSlot2)(void) = &Student::treat;connect(tc, teacherSignal2, st, studentSlot2);//    通过一个按钮信号,链接到上面Teacher的信号,触发上面的信号和槽执行
//    当点击按钮时,按钮发送信号给teacher的信号,teacher信号被触发就会发送信号给student槽函数connect(btn, &QPushButton::clicked, tc, teacherSignal2);

6.断开信号

使用disconnect函数断开信号,函数中的参数就是要断开链接connect里面的参数。

//    点击按钮触发下课,第二种通过信号连接信号实现void(Teacher::*teacherSignal2) (void) = &Teacher::hungry;void(Student::*studentSlot2)(void) = &Student::treat;connect(tc, teacherSignal2, st, studentSlot2);//    通过一个按钮信号,链接到上面Teacher的信号,触发上面的信号和槽执行connect(btn, &QPushButton::clicked, tc, teacherSignal2);//    断开信号disconnect(tc, teacherSignal2, st, studentSlot2);

7.扩展

  1. QT4版本信号和槽写法
//    QT4版本信号和槽connect(tc,SIGNAL(hungry()), st, SLOT(treat()));

相关文章:

QT信号和槽与自定义的信号和槽

QT信号和槽与自定义的信号和槽 1.概述 这篇文章介绍下QT信号和槽的入门知识&#xff0c;通过一个案例介绍如何创建信号和槽&#xff0c;并调用他们。 2.信号和槽使用 下面通过点击按钮关闭窗口的案例介绍如何使用信号和槽。 创建按钮 在widget.cpp文件中创建按钮代码如下 …...

LC:二分查找——杂记

文章目录 268. 丢失的数字162. 寻找峰值 268. 丢失的数字 LC将此题归类为二分查找&#xff0c;并且为简单题&#xff0c;下面记一下自己对这道题目的思考。 题目链接&#xff1a;268.丢失的数字 第一次看到这个题目&#xff0c;虽然标注的为简单&#xff0c;但肯定不能直接排…...

GA/T1400视图库平台EasyCVR多品牌摄像机视频平台前端监控摄像头镜头的基础知识

在现代安全监控系统中&#xff0c;摄像机镜头作为捕捉图像的关键组件&#xff0c;其选择和应用直接影响到监控图像的质量和系统的整体性能。随着技术的发展&#xff0c;摄像机镜头的种类和功能也在不断扩展&#xff0c;以适应各种复杂的监控环境和需求。对于相机成像来讲&#…...

【C++】踏上C++的学习之旅(六):深入“类和对象“世界,掌握编程的黄金法则(一)

文章目录 前言1. "面向过程"和"面向对象"的碰撞1.1 面向过程1.2 面向对象 2. "类"的引入3. "类"的定义3.1 &#x1f349;语法展示&#xff1a;3.2 "类"的两种定义方式3.3 "类"的命名规则 4. 类的访问限定符以及封…...

【物联网技术】ESP8266 WIFI模块在STA模式下作为TCP客户端上电自动进入透传数据模式

前言:讲解如何在ESP8266 WIFI模块在STA模式下作为TCP客户端与网络调试助手(TCP服务器)上电自动进入透传数据模式,而不需重新再发指令配置进入透传模式。 演示视频: ESP8266 WIFI模块在STA模式下作为TCP客户端上电自动进入透传数据模式 wifi模块在STA模式下作为TCP客户端相…...

重构代码之用委托替代继承

在代码重构中&#xff0c;用委托替代继承 是一种用于改善代码设计和提高灵活性的重要技术。它的核心思想是&#xff0c;将子类与父类的直接继承关系转换为委托关系&#xff0c;即子类不再直接继承父类&#xff0c;而是通过持有父类的实例来访问所需的功能。 一、为什么需要用委…...

软件设计师下午题UML15分

一、涉及到的图及对应关系 二、例题 1.用例图和类图的例题 解析及答案 2.状态图和类图的例题 3.通信图和类图例题 例题...

css background-image背景图片轮播

1、CSS背景样式有以下几种&#xff1a; 背景颜色&#xff08;background-color&#xff09;&#xff1a;设置元素的背景颜色。背景图片&#xff08;background-image&#xff09;&#xff1a;设置元素的背景图片。背景重复&#xff08;background-repeat&#xff09;&#xff…...

java---认识异常(详解)

还有大家来到权权的博客~欢迎大家对我的博客提出意见哦&#xff0c;有错误会及时改进的~点击进入我的博客主页 目录 一、异常的概念及体系结构1.1 异常的概念1.2 异常的体系结构1.3异常的分类 二、异常的处理2.1防御式编程2.2 异常的抛出2.3 异常的捕获2.3.1异常声明throws2.3.…...

Linux基础学习笔记

Linux基础学习笔记 Linux目录结构&#xff1a; 具体的目录结构: /bin [重点] (/usr/bin 、 /usr/local/bin) • 是Binary的缩写, 这个目录存放着最经常使用的命令 /home [重点] • 存放普通用户的主目录&#xff0c;在Linux中每个用户都有一个自己的目录&#xff0c;一…...

自动泊车端到端算法 ParkingE2E 介绍

01 算法介绍 自主泊车是智能驾驶领域中的一项关键任务。传统的泊车算法通常使用基于规则的方案来实现。因为算法设计复杂&#xff0c;这些方法在复杂泊车场景中的有效性较低。 相比之下&#xff0c;基于神经网络的方法往往比基于规则的方法更加直观和多功能。通过收集大量专家…...

《手写Spring渐进式源码实践》实践笔记(第十七章 数据类型转换)

文章目录 第十七章 数据类型转换工厂设计实现背景技术背景Spring数据转换实现方式类型转换器&#xff08;Converter&#xff09;接口设计实现 业务背景 目标设计实现代码结构类图实现步骤 测试事先准备属性配置文件转换器工厂Bean测试用例测试结果&#xff1a; 总结 第十七章 数…...

W3C HTML 活动

关于W3C&#xff08;万维网联盟&#xff09;的HTML活动&#xff0c;我们可以从HTML的不同版本的发展历程中了解其主要的活跃时期和贡献。 HTML 2.0&#xff1a;这个版本的HTML是由Internet工程工作小组&#xff08;IETF&#xff09;的HTML工作组于1996年开发的。它是HTML的早期…...

机器学习—为什么我们需要激活函数

如果我们使用神经网络中每个神经元的线性激活函数&#xff0c;回想一下这个需求预测示例&#xff0c;如果对所有节点使用线性激活函数&#xff0c;在这个神经网络中&#xff0c;事实证明&#xff0c;这个大神经网络将变得与线性回归没有什么不同&#xff0c;所以这将挫败使用神…...

软考系统架构设计师论文:论软件的可靠性评价

试题四 论软件的可靠性评价 软件可靠性评价是软件可靠性活动的重要组成部分,既适用于软件开发过程,也可针对最 终软件系统。在软件开发过程中使用软件可靠性评价,可以使用软件可靠性模型,估计软件当前的可靠性,以确认是否可以终止测试并发布软件,同时还可以预计软件要达…...

C++:线程(thread)的创建、调用及销毁

在 C 中&#xff0c;线程的管理主要依赖于标准库 std::thread&#xff0c;自 C11 起&#xff0c;这一功能被标准化&#xff0c;使得我们能够更加方便地创建、管理和销毁线程。这里我们详细讲解线程的创建、调用和销毁流程。 1. 线程的创建 创建线程通常是为了在单独的线程中执…...

关于随身wifi,看了再决定要不要买!2024年最受欢迎的随身wifi品牌推荐!

话费、流量费缴纳起来肉疼&#xff0c;毕竟不是每个月都有很大需求&#xff0c;主打一个该省省该花花。特别是短租人群、在校学生、出差或旅游的人群、追求高性价比的人群&#xff0c;随身Wifi特别实用&#xff0c;出门当WiFi&#xff0c;在家当宽带&#xff0c;两不耽误&#…...

SpringMVC总结 我的学习笔记

SpringMVC总结 我的学习笔记 一、SpringMVC简介1.MVC2.SpringMVC概述3. SpringMVC中的核心组件4.SpringMVC核心架构流程 二、SpringMVC框架实例具体实现使用注解实现 四、数据处理及跳转1.结果跳转方式2.处理器方法的参数与返回值处理提交数据数据显示到前端 五、RestFul风格1.…...

DevCheck Pro手机硬件检测工具v5.33

前言 DevCheck Pro是一款手机硬件和操作系统信息检测查看工具&#xff0c;该软件的功能非常强大&#xff0c;为用户提供了系统、硬件、应用程序、相机、网络、电池等一系列信息查看功能 安装环境 [名称]&#xff1a;DevCheckPro [版本]&#xff1a;5.33 [大小]&a…...

数据分析ReAct工作流

让我用一个数据分析项目的例子来展示plan-and-execute框架的应用。这个例子会涉及数据处理、分析和可视化等任务。 from typing import List, Dict, Any from dataclasses import dataclass import json from enum import Enum import logging from datetime import datetime#…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...

在树莓派上添加音频输入设备的几种方法

在树莓派上添加音频输入设备可以通过以下步骤完成&#xff0c;具体方法取决于设备类型&#xff08;如USB麦克风、3.5mm接口麦克风或HDMI音频输入&#xff09;。以下是详细指南&#xff1a; 1. 连接音频输入设备 USB麦克风/声卡&#xff1a;直接插入树莓派的USB接口。3.5mm麦克…...

FFmpeg avformat_open_input函数分析

函数内部的总体流程如下&#xff1a; avformat_open_input 精简后的代码如下&#xff1a; int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...

第八部分:阶段项目 6:构建 React 前端应用

现在&#xff0c;是时候将你学到的 React 基础知识付诸实践&#xff0c;构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段&#xff0c;你可以先使用模拟数据&#xff0c;或者如果你的后端 API&#xff08;阶段项目 5&#xff09;已经搭建好&#xff0c;可以直接连…...

WebRTC调研

WebRTC是什么&#xff0c;为什么&#xff0c;如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...

Canal环境搭建并实现和ES数据同步

作者&#xff1a;田超凡 日期&#xff1a;2025年6月7日 Canal安装&#xff0c;启动端口11111、8082&#xff1a; 安装canal-deployer服务端&#xff1a; https://github.com/alibaba/canal/releases/1.1.7/canal.deployer-1.1.7.tar.gz cd /opt/homebrew/etc mkdir canal…...