【QT】信号和槽能自动传递参数

news2024/11/15 15:40:53

img

一、前置示例代码

  1. main.cpp
#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);		// 应用程序对象a,在Qt中,应用程序对象,有且仅有一个。
    Widget w;						// 窗口对象w, Widget父类-》 QWidget
    w.show();						// 窗口对象w, 默认不会显示,必须调用show方法显示窗口。
    return a.exec();				// 让应用程序对象a,进入消息循环--》  while(1);
}


  1. widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

signals:
    void isSignal(int signal = 0);
public slots:
    void isSlot(int slot);

};
#endif // WIDGET_H


  1. widget.cpp
#include "widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent) : QWidget(parent)
{
    // 信号和槽的绑定:
    connect(this, &Widget::isSignal, this, &Widget::isSlot);

    // 发送信号:
    emit isSignal(1);
}

Widget::~Widget()
{
}


// 槽函数的实现:
void Widget::isSlot(int slot){
    QString qString;
    qDebug()<< "我是槽函数,我收到的信号是:" << qString.number(slot);
}

程序输出:

我是槽函数,我收到的信号是: "1"

注意:我们并没有直接给槽函数的变量 slot 赋值。 ==槽函数的slot的值,是从信号的signal传递而来的==。




二、信号槽如何传递参数

  1. 信号和槽函数的参数,类型必须进行一一对应,如信号的参数为int,槽函数的参数也为int。

信号:

signals:
    void isSignal(int signal = 0);

槽的定义:

public slots:
    void isSlot(int slot);

槽的实现:

void Widget::isSlot(int slot){
    QString qString;
    qDebug()<< "我是槽函数,我收到的信号是:" << qString.number(slot);
}

发送信号:

emit isSignal(1);

程序输出:

我是槽函数,我收到的信号是: "1"

可以看出,当信号发送后,信号函数的signal 的参数值 “ 1” ,已经成功传递给 槽函数的 接收变量 slot, slot = 1。



  1. 当信号的参数与槽函数的参数数量不同时,只能是信号的参数数量,多于槽函数的参数数量,且前面相同数量的参数类型应一致,信号中多余的参数会被忽略。

信号:

signals:
    void isSignal(int signal = 0, QString s = "我是信号");

槽的定义:

public slots:
    void isSlot(int slot);

槽的实现:

void Widget::isSlot(int slot){
    QString qString;
    qDebug()<< "我是槽函数,我收到的信号是:" << qString.number(slot);
}

发送信号:

emit isSignal(2, "你好");

程序输出:

我是槽函数,我收到的信号是: "2"

可以看出,当信号发送后,信号函数的signal 的参数值 “ 2” ,被成功传递给 槽函数的 接收变量 slot, slot = 2。而 s = “你好” 被忽略。




三、信号和槽发生重载

  1. teacher.h
signals:
    void hungry();

    void hungry(QString foodName);

  1. student.h && student.cpp
public slots:
    void treat();

    void treat(QString foodName);


    
void Student::treat(){
    qDebug()<<"请老师吃饭";
}

void Student::treat(QString foodName){
     qDebug()<<"请老师吃饭,吃:" << foodName.toUtf8().data();
}

  1. widget.h
#include "teacher.h"
#include "student.h"

class Widget : public QWidget
{
public:
    Teacher * ls;
    Student * st;
};

  1. widget.cpp
#include "widget.h"
#include <QPushButton>
#include <QDebug>

//Teacher类 老师类
//student类 学生类
//下课后,老师会触发一个信号,饿了,学生响应信号,请客吃饭


Widget::Widget(QWidget *parent) : QWidget(parent)
{
    //创建一个老师对象
    this->ls = new Teacher(this);
    //创建一个学生对象
    this->st = new Student(this);

     //连接带参数的信号和槽--1
    void (Teacher:: * teacherSignal_void)() = &Teacher::hungry;
    void (Student:: * studentSlot_void)() = &Student::treat;
    connect(ls,teacherSignal_void,st,studentSlot_void);
    emit ls->hungry();

    qDebug()<<"---------------";

    //连接带参数的信号和槽--2
    void (Teacher:: * teacherSignal)(QString) = &Teacher::hungry;
    void (Student:: * studentSlot)(QString) = &Student::treat;
    connect(ls,teacherSignal,st,studentSlot);
    emit ls->hungry("宫爆鸡丁");
}

Widget::~Widget()
{
}


程序输出:

请老师吃饭
---------------
请老师吃饭,吃: 宫爆鸡丁

此外,我们可以通过setParent函数为 QObject 对象设置一个父对象

//创建一个老师对象
this->ls = new Teacher(this);
//创建一个学生对象
this->st = new Student(this);

当父对象被析构时,它会自动析构其所有的子对象。这意味着无需手动管理子对象的销毁,减轻了开发人员的负担,并确保在不再需要这些子对象时,它们会被正确地释放。




四、信号与槽的参数不对应–使用Lambda表达式

widget.cpp

#include "widget.h"
#include <QPushButton>
#include <QDebug>
 
//Teacher类 老师类
//student类 学生类
//下课后,老师会触发一个信号,饿了,学生响应信号,请客吃饭
 
 
Widget::Widget(QWidget *parent) : QWidget(parent)
{
    //创建一个老师对象
    this->zt = new Teacher(this);
    //创建一个学生对象
    this->st = new Student(this);
    //点击一个按钮,再进行下课
    QPushButton * btn = new QPushButton("下课",this);
    setFixedSize(600,400);
 
    //连接带参数的信号和槽
    //指针->地址,函数指针->函数地址
    void (Teacher::*teacherSignal)(QString) = &Teacher::hungry;
    void (Student::*studentSlot)(QString) = &Student::treat;
    connect(zt,teacherSignal,st,studentSlot);
 
    //信号连接信号 一个信号触发另一个信号
    //-----------------------------------------------------
 
    connect(btn,&QPushButton::clicked,zt,teacherSignal);
 
    //-----------------------------------------------------
}
 
 
Widget::~Widget()
{   
}
 

程序报错:

static assertion failed: Signal and slot arguments are not compatible

clicked信号的原型为:

void clicked(bool checked = false)

hungry槽的原型为:

 void hungry(QString foodName);

原因为信号的参数与槽函数参数不对应。 bool型 和 QString 的类型不同。



正确写法:

connect(btn,&QPushButton::clicked,zt,teacherSignal);

改为:

connect(btn,&QPushButton::clicked, this, [this](){
     emit ls->hungry("宫爆鸡丁");
});

或:

connect(btn,&QPushButton::clicked, [this](){
     emit this->ls->hungry("宫爆鸡丁");
});

该connect只有三个参数,在三个参数情况下,默认第三个槽函数的对象是本类this,也就是第三个参数this被省略了。

如果第三个参数是this,第四个参数是Lambda表达式,则可以省略第三个参数 this。

个人实测,第三个参数写ls也行:

connect(btn,&QPushButton::clicked, ls, [this](){
     emit ls->hungry("宫爆鸡丁");
});

程序输出:

请老师吃饭,吃: 宫爆鸡丁
请老师吃饭,吃: 宫爆鸡丁
请老师吃饭,吃: 宫爆鸡丁
请老师吃饭,吃: 宫爆鸡丁




参考连接:

《Qt5:信号和槽使用示例》

qt报错:static assertion failed: Signal and slot arguments are not compatible

信号槽如何传递参数(或带参数的信号槽)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1141431.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023年09月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试&#xff08;1~6级&#xff09;全部真题・点这里 一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 第1题 下列 Python 语句能够正确输出"学而时习之"五个字的是&#xff1f;&#xff08; &#xff09; A: print “…

springboot项目打jar包,运行时提示jar中没有主清单属性

可能性一&#xff1a; 没有在pom中加入maven插件 在pom中加入下方代码即可。 <build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</ve…

电脑定时关机

电脑定时关机 1.右键 管理 2. 3. 4. 5. shutdown.exe/s /f /t 06.点击完成就好了 7.这里面可以 看到定时任务和启动 右键有运行 结束 禁用

【Java 进阶篇】Java Request 继承体系详解

在Java编程中&#xff0c;Request&#xff08;请求&#xff09;是一个常见的概念&#xff0c;特别是在Web开发中。Request通常用于获取来自客户端的信息&#xff0c;以便服务器能够根据客户端的需求提供相应的响应。在Java中&#xff0c;Request通常涉及到一系列类和接口&#…

【Linux】解决缓存锁问题:无法获得锁 /var/lib/dpkg/lock-frontend

今天在运行apt-get update更新软件包后&#xff0c;突然发现安装新的软件出现了这个报错&#xff1a;正在等待缓存锁&#xff1a;无法获得锁 /var/lib/dpkg/lock-frontend。锁正由进程 1855&#xff08;unattended-upgr&#xff09;持有。如图。 这个错误通常是由于其他进程正在…

3DMAX金属屋顶墙面铺设插件使用方法

3DMAX金属屋顶墙面铺设插件教程 3DMAX金属屋顶墙面铺设插件&#xff0c;一键生成金属板屋顶、金属外墙面板&#xff0c;是一款非常实用的建筑建模插件。 【适用版本】 3dMax7或更新版本 【使用方法】 1.启动3dMax软件&#xff0c;打开&#xff08;或创建&#xff09;场景文件…

《持续交付:发布可靠软件的系统方法》- 读书笔记(八)

持续交付&#xff1a;发布可靠软件的系统方法&#xff08;八&#xff09; 第 8 章 自动化验收测试8.1 引言8.2 为什么验收测试是至关重要的8.2.1 如何创建可维护的验收测试套件8.2.2 GUI 上的测试 8.3 创建验收测试8.3.1 分析人员和测试人员的角色8.3.2 迭代开发项目中的分析工…

Java学习 3. 习题 1.

一、 1. 2. 3. 4. 5. 二、 1. 2. 3. 4. 5. 6. 7. 8.

Vsan数据恢复—Vsan存储断电导致虚拟机无法启动的数据恢复案例

Vsan分布式存储故障&检测&#xff1a; 异常断电导致一台vsan存储设备上层虚拟机无法启动。 将故障Vsan存储上的所有磁盘编号后取出&#xff0c;由北亚企安的硬件工程师对vsan存储上的所有硬盘进行物理故障检测&#xff0c;经过检测没有发现硬盘存在物理故障。 vsan存储结构…

北邮22级信通院数电:Verilog-FPGA(7)第七周实验(2):BCD七段显示译码器(关注我的uu们加群咯~)

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 关注作者的uu们可以进群啦~ 一.verilog代码 1.1 …

【数据结构】选择排序

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;浅谈数据结构 &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 直接选择、堆排序 1. 直接选择排序2…

网工内推 | 急招网工,思科、华为认证优先,法定节假日三薪

01 江苏臻云技术 招聘岗位&#xff1a;网络工程师 职责描述&#xff1a; 1、负责落实数据中心机房日常网络监测及巡检任务&#xff1b; 2、负责数据中心网络设备日常监控、变更、维护、巡检&#xff1b; 3、负责日常巡检报告、故障维护报告、变更申请的文档的编制&#xff1b;…

微信小程序如何使用地球半径计算两组经纬度点之间的距离(自身位置与接口返回位置)【上】

目录 1.配置位置权限 2.获取当前自身经纬度 3. 请求接口拿到返回经纬 4. 循环取每一项的经纬 5.如何判断是否打开了定位权限 6.进行距离计算操作 7.运行效果 8.完整代码 首先在使用小程序时&#xff0c;请求的接口一定要去配置合法域名&#xff0c;才能够进行接下来…

【开源】基于SpringBoot的车险自助理赔系统的设计和实现

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 角色管理模块2.3 车辆档案模块2.4 车辆理赔模块2.5 理赔照片模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 角色表3.2.2 车辆表3.2.3 理赔表3.2.4 理赔照片表 四、系统展示五、核心代码5.1 查询车…

基于机器视觉的行人口罩佩戴检测 计算机竞赛

简介 2020新冠爆发以来&#xff0c;疫情牵动着全国人民的心&#xff0c;一线医护工作者在最前线抗击疫情的同时&#xff0c;我们也可以看到很多科技行业和人工智能领域的从业者&#xff0c;也在贡献着他们的力量。近些天来&#xff0c;旷视、商汤、海康、百度都多家科技公司研…

【C++初阶】类和对象——构造函数析构函数拷贝构造函数

个人主页点击直达&#xff1a;小白不是程序媛 C系列专栏&#xff1a;C头疼记 目录 前言 类的6个默认成员函数 构造函数 概念 构造函数的特性 析构函数 概念 析构函数特性 拷贝构造函数 概念 拷贝构造函数特性 总结 前言 上篇文章我们对于C中的类有了初步的认识和…

【运维知识大神篇】两种方法,一键部署ElasticSearch集群(Shell+Ansible自动化部署)

本篇文章给大家介绍一下用Shell和Ansible两种方式&#xff0c;去一键部署ES&#xff08;ElasticSearch&#xff09;集群&#xff0c;实现在集群部署中的批量化操作&#xff0c;享受自动化部署的魅力。 准备主机 主机名IPcpudiskmemoryAnsible10.0.0.612C20G2GELK10410.0.0.10…

Linux必备技能:掌握的必会命令

1 rpm查看程序配置文件 rpm -qc httpd2 rpm查看系统已经安装的相关的包 rpm -qa | grep httpd3 netstat查看服务支持的端口 netstat -anltupe | grep httpd

初识HTML超文本标记语言

文章目录 前端简介引入前端三剑客什么是HTML&#xff1f;超文本传输协议前戏HTTP超文本传输协议1.什么是HTTP协议2.四大特性3.数据格式4.响应状态码 基于HTTP协议搭建HTMLHTML简介 前端简介 引入 前端&#xff1a;与用户直接打交道的操作界面都可以称之为前端(那些炫酷的页面)…

自动化工具-文件清单对比

博客主页&#xff1a;https://tomcat.blog.csdn.net 博主昵称&#xff1a;农民工老王 主要领域&#xff1a;Java、Linux、K8S 期待大家的关注&#x1f496;点赞&#x1f44d;收藏⭐留言&#x1f4ac; 目录 背景代码使用 背景 最近的工作中&#xff0c;领导需要比较指定两个文…