Qt---信号和槽
一、信号和槽机制
所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。

连接函数:connect
参数:
参数1:信号的发送者
参数2:发送的信号(函数地址)
参数3:信号的接收者
参数4:处理的槽函数(函数的地址)
优点:松散耦合
实现点击按钮关闭窗口的案例:
connect(myBtn,&MyPushButton::clicked,this,&myWidget::close); //connect(myBtn,&QPushButton::clicked,this,&QPushButton::close);使用父类
二、自定义信号和槽
自定义信号
写到signals 下返回void
需要声明,不需要实现可以有参数,可以重载
自定义槽函数
返回void
需要声明,也需要实现可以有参数,可以重载
写到public slot下或者public或者全局函数触发自定义的信号
emit自定义信号
案例:下课后,老师触发饿了信号,学生响应信号,请客吃饭
student.h
#ifndef STUDENT_H
#define STUDENT_H#include <QObject>class Student : public QObject
{Q_OBJECT
public:explicit Student(QObject *parent = nullptr);//返回值void,需要声明也需要实现//可以有参数,可以发生重载void treat();signals:};#endif // STUDENT_H
student.cpp
#include "student.h"
#include<QDebug>Student::Student(QObject *parent) : QObject(parent)
{}void Student::treat()
{qDebug()<<"请老师吃饭";
}
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
teacher.cpp
#include "teacher.h"Teacher::Teacher(QObject *parent) : QObject(parent)
{}
widget.h
#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();private:Ui::Widget *ui;Teacher *zt;Student *st;void ClassIsOver();
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"//Teacher类 老师类
//Student类 学生类
//下课后,老师触发一个信号,饿了,学生响应信号,请客吃饭
Widget::Widget(QWidget *parent): QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);//创建一个老师对象this->zt = new Teacher(this);//创建一个学生对象this->st = new Student(this);//老师饿了 学生请客的连接connect(zt,&Teacher::hungry,st,&Student::treat);//调用下课函数ClassIsOver();
}void Widget::ClassIsOver()
{//下课函数,调用后触发老师饿了的信号emit zt->hungry();
}Widget::~Widget()
{delete ui;
}
三、自定义信号和槽发生重载的解决办法
需要利用函数指针,明确指向函数的地址
void(Teacher:: *teacherSignal)(QString foodName) = &Teacher::hungry; void(Student:: *studentSlot)(QString foodName) = &Student::treat;QString转成char*
.toUtf8()先转为AByteArray
.date再转为char*
student.h
#ifndef STUDENT_H
#define STUDENT_H#include <QObject>class Student : public QObject
{Q_OBJECT
public:explicit Student(QObject *parent = nullptr);//返回值void,需要声明也需要实现//可以有参数,可以发生重载void treat();void treat(QString foodName);//重载版本声明signals:};#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)//重载版本实现
{//QString->char * 先转成QByteArray(.toUtf8())再转char *(.data)qDebug()<<"请老师吃饭,老师要吃:"<<foodName.toUtf8().data();
}
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();void hungry(QString);//重载版本};#endif // TEACHER_H
teacher.cpp
#include "teacher.h"Teacher::Teacher(QObject *parent) : QObject(parent)
{}
widget.h
#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();private:Ui::Widget *ui;Teacher *zt;Student *st;void ClassIsOver();
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"//Teacher类 老师类
//Student类 学生类
//下课后,老师触发一个信号,饿了,学生响应信号,请客吃饭
Widget::Widget(QWidget *parent): QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);//创建一个老师对象this->zt = new Teacher(this);//创建一个学生对象this->st = new Student(this);// //老师饿了 学生请客的连接
// connect(zt,&Teacher::hungry,st,&Student::treat);// //调用下课函数
// ClassIsOver();//连接带参数的信号和槽//指针->地址//函数指针->函数地址void(Teacher:: *teacherSignal)(QString foodName) = &Teacher::hungry;void(Student:: *studentSlot)(QString foodName) = &Student::treat;connect(zt,teacherSignal,st,studentSlot);ClassIsOver();}void Widget::ClassIsOver()
{//下课函数,调用后触发老师饿了的信号//emit zt->hungry();emit zt->hungry("宫保鸡丁");//重载版本
}Widget::~Widget()
{delete ui;
}
说明:
connect(zt,&Teacher::hungry,st,&Student::treat);
若使用老师饿了的地址&Teacher::hungry和学生请客的地址&Student::treat则不能区分是否带参,故出错(带参和不带参地址一样)
解决方案:
对于函数地址&Teacher::hungry,我们使用函数指针指向函数地址
函数指针定义方式:函数返回值类型(*指针变量名)(函数参数列表);如下:
void( *teacherSignal)(QString foodName) = &Teacher::hungry;
在声明成员函数的函数地址的时候,要把成员函数的作用域放在指针前面,正确写法如下:
void(Teacher:: *teacherSignal)(QString foodName) = &Teacher::hungry;
四、信号连接信号

#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>//Teacher类 老师类
//Student类 学生类
//下课后,老师触发一个信号,饿了,学生响应信号,请客吃饭
Widget::Widget(QWidget *parent): QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);//创建一个老师对象this->zt = new Teacher(this);//创建一个学生对象this->st = new Student(this);// //老师饿了 学生请客的连接
// connect(zt,&Teacher::hungry,st,&Student::treat);// //调用下课函数
// ClassIsOver();//连接带参数的信号和槽//指针->地址//函数指针->函数地址void(Teacher:: *teacherSignal)(QString foodName) = &Teacher::hungry;void(Student:: *studentSlot)(QString foodName) = &Student::treat;connect(zt,teacherSignal,st,studentSlot);// ClassIsOver();//点击一个下课的按钮,再触发下课QPushButton *btn = new QPushButton("下课",this);//重置窗口大小btn->resize(100,40);//点击按钮 触发下课//connect(btn,&QPushButton::clicked,this,&Widget::ClassIsOver);//无参信号和槽连接void(Teacher:: *teacherSignal2)(void) = &Teacher::hungry;void(Student:: *studentSlot2)(void) = &Student::treat;connect(zt,teacherSignal2,st,studentSlot2);//信号和信号连接connect(btn,&QPushButton::clicked,zt,teacherSignal2);//断开信号//disconnect(zt,teacherSignal2,st,studentSlot2);}void Widget::ClassIsOver()
{//下课函数,调用后触发老师饿了的信号//emit zt->hungry();emit zt->hungry("宫保鸡丁");
}Widget::~Widget()
{delete ui;
}
运行:点击按钮下课则输出,但窗口不会关闭。断开信号不注释,点击按钮则不输出

拓展:
1.信号可以连接信号
2.信号可以连接多个槽函数(点击按钮先输出再关闭窗口[连接close即可])3.多个信号可以连接一个槽函数
4.信号和槽函数的参数必须―—对应
5.信号的参数个数可以多于槽的参数的个数
五、lambda表达式
Lambda表达式用于定义并创建匿名的函数对象
[]标识符 匿名函数
=:值传递
&:引用传递参数
()参数
{}实现体
mutatle修饰值传递变量,可以修改拷贝出的数据,改变不了本体返回值()[] ->init {}
labmda表达式最常用 [=](){}
//利用lambda表达式实现点击按钮关闭窗口QPushButton *btn2 = new QPushButton;btn2->setText("关闭");btn2->move(100,0);btn2->setParent(this);connect(btn2,&QPushButton::clicked,this,[=](){this->close();emit zt->hungry("宫保鸡丁");});
运行,点击下课输出"请老师吃饭",点击关闭输出"请老师吃饭,老师要吃: 宫保鸡丁"同时关闭窗口
输出如下所示:


作业:
两个按钮实现:
#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>
#include<QWidget>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton *open_btn = new QPushButton("open",this);open_btn->resize(80,30);QPushButton *close_btn = new QPushButton("close",this);close_btn->resize(80,30);close_btn->move(0,100);QWidget *window = new QWidget;window->setWindowTitle("other_window");setWindowTitle("work_window");connect(open_btn,&QPushButton::clicked,window,[=](){window->show();});connect(close_btn,&QPushButton::clicked,window,[=](){window->close();});}Widget::~Widget()
{delete ui;
}
一个按钮实现:
#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>
#include<QWidget>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton *btn = new QPushButton("open",this);setWindowTitle("work_window");QWidget *window = new QWidget;window->setWindowTitle("other_window");connect(btn,&QPushButton::clicked,window,[=](){if(btn->text()=="open"){btn->setText("close");window->show();}else if(btn->text()=="close"){btn->setText("open");window->close();}});}Widget::~Widget()
{delete ui;
}相关文章:
Qt---信号和槽
一、信号和槽机制 所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号…...
POCEXP编写—文件上传案例
POC&EXP编写—文件上传案例 1. 前言2. 文件上传案例2.1. Burp抓包2.2. 基础代码实践2.2.1. 优化代码 2.3. 整体代码2.3.1. 木马测试 1. 前言 之前的文章基本上都是一些相对来说都是验证类的或者说是一些代码执行类的,相对来说都不是太复杂,而这篇会…...
C#知识|上位机UI设计-详情窗体设计思路及流程(实例)
哈喽,你好啊,我是雷工! 上两节练习记录了登录窗体和主窗体的实现过程,本节继续练习内容窗体的实现,以下为练习笔记。 01 详情窗体效果展示: 02 添加窗体并设置属性 在之前练习项目的基础上添加一个Windows窗体,设置名称为:FrmIPManage.cs 设置窗体的边框和标题栏的外…...
目标检测——印度车辆数据集
引言 亲爱的读者们,您是否在寻找某个特定的数据集,用于研究或项目实践?欢迎您在评论区留言,或者通过公众号私信告诉我,您想要的数据集的类型主题。小编会竭尽全力为您寻找,并在找到后第一时间与您分享。 …...
Zotero Word中插入带超链接的参考文献
Zotero 超链接 找了好多原代码,最接近能实施的为: https://blog.csdn.net/weixin_47244593/article/details/129072589 但是,就是向他说的一样会报错,我修改了代码,遇见报错的地方会直接跳过不执行,事后找…...
如何在服务器上下载,解压github上的代码
在github上找到对应仓库,找到平时download zip的地方,右键它,复制链接。在远程的终端里使用wget 链接 命令就可以得到zip了。 解压方法: -c :新建打包文件 -t :查看打包文件的内容含有哪些文件名 -x &…...
BGP学习二:BGP通告原则,BGP反射器,BGP路径属性细致讲解,新手小白无负担
目录 一.AS号 二.BGP路由生成 1.network 2.import-route引入 三.BGP通告原则 1.只发布最优且有效的路由 2.从EBGP获取的路由,会发布给所有对等体 3.水平分割原则 4.IBGP学习BGP默认不发送给EBGP,但如果也从IGP学习到了这条路由,就发…...
Docker学习(带图详细)
一、安装docker 参考官方文档:https://docs.docker.com/engine/install/centos/ 查看系统版本 [rootlocalhost ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) [rootlocalhost ~]# [rootlocalhost ~]# uname -a Linux localhost.localdomai…...
RabbitMQ 如何使用延迟队列
RabbitMQ 如何使用延迟队列 目录 前置条件场景描述RabbitMQ 延迟队列机制实现步骤 1. 安装 RabbitMQ 延迟队列插件2. 创建延迟队列和交换机3. 发布延迟消息4. 消费延迟消息 示例代码 1. 延迟队列配置2. 发布消息的 Producer 代码3. 消费消息的 Consumer 代码 注意事项 前置条…...
【C++】栈和队列
目录 前言 一、stack 1. 栈的定义 2. 成员函数 二、queue 1. 队列的定义 2. 成员函数 三、priority_queue 1. 优先队列的定义 2. 成员函数 前言 栈和队列是STL中很重要的两个容器,栈的特点是先进后出;队列的特点是先进先出。还有优先队列&…...
常用的预编码算法学习
一、概况 预编码算法的常用实现方式有以下几种: 1. 间隔预编码(Interval Pre-coding):该算法将原始数据分成若干个间隔,然后对每个间隔内的数据进行编码。间隔的长度可以根据具体情况进行选择,常见的间隔长度有固定长度和可变长度两种方式。 2. 迭代预编码(Iterative…...
人才培养计划大纲
构建全面而高效的人才培养规划 文章大纲: 引言 人才培养的重要性当前人才培养面临的挑战文章目的与结构人才培养规划的基本概念 定义与内涵人才培养规划与企业战略的关系人才培养规划的基本原则人才培养规划的现状分析 当前人才培养规划的实践情况存在的问题与不足…...
多语言环境下的正则表达式实战:校验整数、小数
在软件开发中,正则表达式是验证用户输入数据格式的强大工具,特别是在处理表单验证时。本文将通过JavaScript、Java、Python、C、Rust、Go、C六种编程语言展示如何使用正则表达式来校验输入是否为整数或小数,特别强调小数点后最多保留两位的场…...
过拟合和欠拟合的学习
1.什么拟合 就是说这个曲线能不能很好地描述某些样本数据,并且拥有较好的泛化能力。 2.什么是过拟合 过拟合就是曲线太过于贴切训练数据的特征了,在训练集上表现得非常优秀,近乎完美的预测/区分了所有得数据,但是在新的测试集上…...
中间件的使用
中间件是全局使用 工厂函数定义中间件 middleware.py # 工厂函数的中间件 def simple_middleware(get_response):def middleware(request):print("在视图函数处理之前执行、、、、、")response get_response(request)print("在视图函数处理之后执行。。。。…...
阿里云OSS权限开通步骤及最佳实践
在阿里云云计算平台中,对象存储服务(OSS)是一种高度可扩展的云存储服务,提供了安全、可靠、低成本的数据存储解决方案。在使用OSS时,正确配置权限是至关重要的,以确保数据的安全性和访问控制。本文将介绍阿…...
【Python贪吃蛇】:编码技巧与游戏设计的完美结合
文章目录 🔥一、运行效果💥二、游戏教程✈1. 导入模块❤️2. 初始化游戏元素☔3. 改变蛇移动的方向👊4. 绘制方块🚀5. 检查蛇头是否在游戏区域内🌈6. 定义蛇的移动函数🎬7. 绑定键盘事件 ⭐三、完整代码 &a…...
2024.5.19 机器学习周报
引言 Abstract 文献阅读 1、题目 X-HRNET: TOWARDS LIGHTWEIGHT HUMAN POSE ESTIMATION WITH SPATIALLY UNIDIMENSIONAL SELF-ATTENTION 2、引言 高分辨率表示是人体姿态估计实现高性能所必需的,随之而来的问题是高计算复杂度。特别地,主要的姿态估…...
母亲节祝福html源码示例
创建一个完整的HTML页面,我可以为您提供一个简单的HTML模板,其中包含一些示例性的祝福语,并添加一些注释以帮助您理解如何扩展内容。 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8&qu…...
微信小程序开发中的权限管理与用户身份验证:守护数据安全与用户体验
微信小程序开发中的权限管理与用户身份验证:守护数据安全与用户体验 引言 在微信小程序开发中,权限管理和用户身份验证是确保数据安全、保护用户隐私以及提供个性化服务的关键环节。本文将深入探讨微信小程序中如何实现权限管理和用户身份验证…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
