(3)Qt——信号槽

news2024/12/25 10:35:37

目录

1.信号槽的概念**

2.信号槽的连接***

2.1自带信号 → 自带槽

2.2 自带信号 → 自定义槽

2.3 自定义信号

3. 参数传递**

3.1 全局变量

3.2 信号槽传参

4. 对应关系**

4.1 一对多

4.2 多对一


1.信号槽的概念**

信号槽指的是信号函数与槽函数的连接,可以使用不同的对象通过信号槽连接在一起,从而实现对象之间的通信。

可以把信号槽的连接认为是对象之间的一种约定:如果.......,则.......

信号槽是Qt新增的特性,C++是不支持的,使用信号槽的前提条件:

1)通信的对象的类中要有Q_OBJECT

2)通信的对象必须继承自(包括间接继承)自QObject 【所以Qt对象的基类】类

2.信号槽的连接***

信号槽是一种约定,主要通过以下实现

// 参数1:信号发射者 是一个名词,因果关系中的因,表示发射信号函数的对象
// 参数2:信号函数的名称 是一个动词,需要使用SINGNAL()包裹,因果关系的因,表示动作
// 参数3:信号接收者 是一个名称,因果关系中的果,表示执行动作(操作函数)的对象
// 参数4:槽函数的名称 是一个动词,需要使用SLOT()包裹,因果关系中的果,表示动作
QObject::connect(const QObject * sender, 
				    const char * signal, 
				    const QObject * receiver, 
				    const char * method) [static]

依次通过三种方式讲解信号槽的连接

1)自带信号自带槽

2)自带信号自定义槽

3)自定义信号自带/自定义槽

2.1自带信号 → 自带槽

这是最简单的一种信号槽连接方式,因为信号函数和槽函数都在Qt源代码中实现了,只需要查询文档找到名称手动连接即可。

【例子】点击按钮,关闭窗口

分析:

参数1:按钮对象

参数2:点击信号

参数3:窗口对象

参数4:关闭槽

 

 

 

 

 

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include 
#include 

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    QPushButton* btn;
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    resize(400,400);
    btn = new QPushButton("关",this);
    btn->move(200,200);
    // 连接信号槽
    // 参数1:按钮对象
    //	参数2:点击信号 clicked
    //	参数3:窗口对象
    //	参数4:关闭槽 close
    connect(btn,SIGNAL(clicked()),this,SLOT(close()));
}

Dialog::~Dialog()
{
    delete btn;
}

2.2 自带信号 → 自定义槽

当槽函数完成的功能比较复杂时,Qt的源代码无法完全覆盖这样的功能,此时需要程序员手动写一个槽函数,并实现和连接。

需要注意的是槽函数实际上是一种特殊的成员函数。

【例子】点击按钮,把窗口向右下角移动,并输出当前的窗口坐标。

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include 
#include 
#include 

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    QPushButton* btn;

    // 声明自定义槽函数
private slots:
    void mySlot();
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    resize(400,400);
    btn = new QPushButton("关",this);
    btn->move(200,200);
    // 连接信号槽
    //   参数1:按钮对象
    //	参数2:点击信号 clicked
    //	参数3:this
    //	参数4:自定义槽函数mySlot
    connect(btn,SIGNAL(clicked()),this,SLOT(mySlot()));
}

// 定义槽函数
void Dialog::mySlot()
{
    // 先获得当前窗口的坐标
    int x = this->x();
    int y = this->y();
    // 移动窗口
    move(x+10,y+10);
    // 输出当前坐标值
    qDebug() << this->x() << this->y();
}

Dialog::~Dialog()
{
    delete btn;
}

2.3 自定义信号

自定义信号主要用户后期一些特殊的情况,目前还没发举例,因此基于下面的案例,强行使用,并不是问题的最优解。

需要注意的是,信号函数没有权限,只有声明没有定义。不能调用信号函数,只能发射信号函数。

【例子】点击按钮,关闭窗口。

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include 
#include 

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    QPushButton* btn;

    // 自定义槽函数
private slots:
    void mySlot();

    // 声明自定义信号
signals:
    void mySignal();
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    resize(500,500);
    btn = new QPushButton("关闭",this);
    btn->move(250,250);

    // 连接第一个信号槽
    connect(btn,SIGNAL(clicked()),
            this,SLOT(mySlot()));
    // 连接第二个槽函数
    connect(this,SIGNAL(mySignal()),
            this,SLOT(close()));
}

// 定义槽函数
void Dialog::mySlot()
{
    // 发射自定义信号函数
    emit mySignal();
}

Dialog::~Dialog()
{
    delete btn;
}

3. 参数传递**

3.1 全局变量

可以借助一个全局(根据实际应用的范围来指定)可访问的变量来实现。

【例子】点击按钮,按钮上显示点击的次数。

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QPushButton>

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    QPushButton *btn;
    // 计数变量
    int count;

    // 自定义槽函数
private slots:
    void mySlot();
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    count = 0; // 赋予初始值
    resize(400,400);
    btn = new QPushButton("0",this);
    //btn->move(200,200);
    btn->setGeometry(150,150,50,50);
    // 连接信号槽
    connect(btn,SIGNAL(clicked()),
            this,SLOT(mySlot()));
}

void Dialog::mySlot()
{
    // 计数+1
    count++;
    // int → QString
    // QString QString::number(int n) [static]
    QString text = QString::number(count);
    // 设置按钮的新文字
    btn->setText(text);
}

Dialog::~Dialog()
{
    delete btn;
}

运行结果:

3.2 信号槽传参

本节强行使用信号槽传参,此方法主要用于后续复杂问题的解决。

【例子】点击按钮,按钮上显示点击的次数。

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include 
#include 

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    QPushButton* btn;
    int count = 0; // 计数

private slots:
    void mySlot1(); // 自定义槽函数1
    void mySlot2(int); // 自定义槽函数2

signals:
    // 自定义信号槽,带参数!!!
    void mySignal(int);
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    resize(400,400);
    btn = new QPushButton("0",this);
    btn->move(200,200);

    // 第一个信号槽连接
    connect(btn,SIGNAL(clicked()),
            this,SLOT(mySlot1()));
    // 第二个信号槽的连接
    connect(this,SIGNAL(mySignal(int)),
            this,SLOT(mySlot2(int)));
}

void Dialog::mySlot1()
{
    // 增加计数
    count++;
    // 发射自定义信号
    emit mySignal(count);
}

void Dialog::mySlot2(int count)
{
    // int → QString
    QString text = QString::number(count);
    // 更新显示
    btn->setText(text);
}

Dialog::~Dialog()
{
    delete btn;
}

需要注意的是:

  • 理论上可以通过信号槽传递任意多个参数。
  • 信号的参数个数必须大于等于槽的参数个数。
  • 参数类型必须匹配。

4. 对应关系**

4.1 一对多

同一个信号可以连接多个槽函数。

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include 
#include 
#include 

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    QPushButton *btn1;
    QPushButton *btn2;

private slots:
    void mySlot1();
    void mySlot2();
    void mySlot3();
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    resize(300,400);
    btn1 = new QPushButton("一对多",this);
    btn1->move(100,200);
    // 一对多
    connect(btn1,SIGNAL(clicked()), this,SLOT(mySlot1()));
    connect(btn1,SIGNAL(clicked()),this,SLOT(mySlot2()));
    //disconnect(btn1,SIGNAL(clicked()),this,SLOT(mySlot2()));

    btn2 = new QPushButton("一对多",this);
    btn2->move(100,250);
    connect(btn2,SIGNAL(clicked()),this,SLOT(mySlot3()));
}

void Dialog::mySlot1()
{
    qDebug() << "A";
}

void Dialog::mySlot2()
{
    qDebug() << "B";
}

void Dialog::mySlot3()
{
    // 槽函数也是成员函数,直接调用mySlot1和2
    mySlot1();
    mySlot2();
}

Dialog::~Dialog()
{
    delete btn1;
    delete btn2;
}

4.2 多对一

多个信号也可以连接同一个槽函数,代码略。

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

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

相关文章

AI绘图入门 安装 stable-diffusion-webui

下面介绍了N卡&#xff0c;A卡&#xff0c;或CPU跑 stable-diffusion-webui的方法。 1.安装python 3.10.x https://www.python.org/downloads/ 2.安装Git https://git-scm.com/downloads 【非必要】打开代理工具&#xff08;比如clash&#xff09;然后在cmd配置git的http和…

软件测试相关概念

✏️作者&#xff1a;银河罐头 &#x1f4cb;系列专栏&#xff1a;JavaEE &#x1f332;“种一棵树最好的时间是十年前&#xff0c;其次是现在” 目录 需求需求的定义测试人员眼中的需求为什么需求对测试人员如此重要如何深入理解需求 测试用例定义为什么要有测试用例 软件错误…

IT服务规划设计笔记

规划设计处于整个IT服务生命周期中的前端&#xff0c;其主要目的在于&#xff1a; &#xff08;1&#xff09;设计满足业务需求的IT服务 &#xff08;2&#xff09;设计SLA、测量方法和指标 &#xff08;3&#xff09;设计服务过程及其控制方法 &#xff08;4&#xff09;规…

learn_C_deep_9 (汇编角度理解return的含义、const 的各种应用场景)

return 关键字 不知道我们大家是否有一个疑惑&#xff1a;我们下载一个大型游戏软件&#xff08;王者荣耀&#xff09;&#xff0c;都要花几个小时去下载&#xff0c;但是一旦我们游戏连输&#xff0c;想要删除这个软件的时候&#xff0c;它仅仅只需要十几秒&#xff0c;这是为…

主题建模和文本聚类:理论与实践

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

真题详解(3FN)-软件设计(六十九)

真题详解&#xff08;构造二叉树&#xff09;-软件设计&#xff08;六十八)https://blog.csdn.net/ke1ying/article/details/130536155 学生信息学生id姓名性别1{家长ID}*班主任班级。 解析&#xff1a;当存在1对多的情况&#xff0c;要写个1{}*&#xff0c;中间用{}。 ()表…

一篇学会Gitlab搭建及使用

目录 一、Gitlab介绍 1、什么是Gitlab 二、搭建gitlab并实现ssl 1、配置yum源或下载gitlab包 2、安装依赖软件及获取GPG密钥 3、安装gitlab-ce 4、创建私有密钥 5、创建私有证书 6、创建CRT签名证书 7、利用openssl签署pem 证书 8、配置证书到gitlab 9、初始化gitla…

读书笔记:《图解CIO工作指南》

《图解CIO工作指南》第 4 版&#xff0c;日 . 野村综合研究所系统咨询事业本部 著&#xff0c;周自恒 译 大数据、云计算时代下的IT战略和IT实务 CIO工作&#xff1a;IT管理、IT架构、IT实践 以着眼企业未来的观点进行构思&#xff1a;可视化&#xff08;业务与系统&am…

初始化vue中data中的数据

当组件的根元素使用了v-if的时候, 并不会初始化data中的数据 如果想完全销毁该组件并且初始化数据,需要在使用该组件的本身添加v-if 或者是手动初始化该组件中的数据 初始化化数据的一些方法 Object.assign(this.$data, this.$options.data()) this.$data&#xff1a;当前的da…

TortoiseGit(大乌龟)安装教程(Git 图形化工具,告别手敲命令)

TortoiseGit安装教程 1. 下载TortoiseGit 官方下载地址&#xff1a;https://tortoisegit.org/download/ 自行选择下载对应版本&#xff08;大部分位64位&#xff09;&#xff0c;进行下载 2. 安装TortoiseGit 打开安装包&#xff0c;如下图所示&#xff1a; 点击 Next&…

IDM绿色最新2023中文版磁力下载工具

Internet Download Manager&#xff08;idm&#xff09;是一款优秀的多线程下载工具。它支持自动捕获剪贴板及浏览器及流媒体网站的音视频下载链接&#xff0c;还有批量队列下载、静默下载、站点抓取等众多功能选项&#xff0c;可以说是 Windows 平台上功能最为强大的多线程下载…

通过栈/队列/优先级队列/了解容器适配器,仿函数和反向迭代器

文章目录 一.stack二.queue三.deque&#xff08;双端队列&#xff09;四.优先级队列优先级队列中的仿函数手搓优先级队列 五.反向迭代器手搓反向迭代器 vector和list我们称为容器&#xff0c;而stack和queue却被称为容器适配器。 这和它们第二个模板参数有关系&#xff0c;可以…

录屏界鼻祖Camtasia 2023中文版功能介绍/下载安装激活教程

随着网络科技的迅速发展&#xff0c;所以对于电脑的使用率也就越来越高了&#xff01;然而&#xff0c;也可能跟这有关系&#xff0c;目前各种类型的软件层出不穷&#xff0c;当然也就包括了电脑录屏软件。这给我们造成了一些困难&#xff0c;究竟哪一款适合自己呢&#xff1f;…

DMA的补充笔记

DMA有两个总线&#xff1a; 1、DMA存储器总线&#xff1a;DMA通过该总线来执行存储器数据的传入和传出。 2、DMA外设总线&#xff1a;DMA通过该总线访问AHB外设&#xff08;AHB主要是针对高效率、高频宽以及快速系统模块所设计的&#xff0c;主要有Flash 存储器、复位和时钟控…

栈和队列OJ题思路分享之栈和队列互换(C语言实现)

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:刷题分享⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你刷更多C语言和数据结构的题!   &#x1f51d;&#x1f51d; 栈和队列刷题分享二 1. 前言⚡…

基于人类反馈的强化学习(RLHF) 理论

gpt 进程 GPT-1 用的是无监督预训练 有监督微调&#xff0c;只有简单的单向语言模型任务&#xff1b;GPT-2用的是纯无监督预训练&#xff0c;使用更多的数据&#xff0c;更大的模型&#xff0c;又新增了几个辅助的训练任务&#xff1b;GPT-3 沿用了 GPT-2 的纯无监督预训练&a…

postgresql standby启动流程分析

专栏内容&#xff1a;postgresql内核源码分析个人主页&#xff1a;我的主页座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物&#xff0e; 目录 前言 概述 原理机制 关键流程 备节点启动 walreceiver启动的时机 结尾 前…

网络协议与攻击模拟-07-TCP连接-三次握手

传输层协议 1.TCP 2.UDP TCP 协议 回顾内容 1&#xff0e;传输层功能&#xff1a;定义应用层协议数据报文的端口号&#xff0c;流量控制 2&#xff0e;对原始数据进行分段处理 传输层所提供服务 1&#xff0e;传输连接服务 2&#xff0e;数据传输服务&#xff1a;流量控制…

基于条纹投影的物体三维形貌测量理论与仿真实验-含Matlab代码

▒▒本文目录▒▒ ✳️ 一、引言✳️ 二、条纹投影原理✳️ 2.1 相移轮廓术✳️ 2.2 傅里叶变换轮廓术 ✳️ 三、仿真分析✳️ 3.1 傅里叶变换轮廓术仿真实验✳️ 3.1.1 Matlab代码获取 ✳️ 3.2 相移轮廓术仿真实验✳️ 3.2.1 Matlab代码获取 ✳️ 参考文献 ✳️ 一、引言 基…

玩转axios, 我行你行吗

一.axios是什么&#xff1f; Axios是一个基于Promise网络请求库,作用于node.js和浏览器中, 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。 在服务端它使用原生node.js http模块&#xff0c;而在客户端(浏览端)则使用XMLHttpRequests。 二.特性 1.从浏览器创…