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…...
微信小程序开发中的权限管理与用户身份验证:守护数据安全与用户体验
微信小程序开发中的权限管理与用户身份验证:守护数据安全与用户体验 引言 在微信小程序开发中,权限管理和用户身份验证是确保数据安全、保护用户隐私以及提供个性化服务的关键环节。本文将深入探讨微信小程序中如何实现权限管理和用户身份验证…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...

接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...