一次吃透Qt中信号与槽(包含信号与槽的使用,自定义以及重构示例,建议收藏)

2023-11-18

1、Qt中信号和槽

信号与槽

信号与槽(Signal & Slot)是 Qt 编程的基础,也是 Qt 的一大创新。因为有了信号与槽的编程机制,在 Qt 中处理界面各个组件的交互操作时变得更加直观和简单。它可以让应用程序编程人员把这些互不了解的对象绑定在一起。

信号(Signal)

信号(Signal)就是在特定情况下被发射的事件,例如PushButton 最常见的信号就是鼠标单击时发射的 clicked() 信号,一个 ComboBox 最常见的信号是选择的列表项变化时发射的 CurrentIndexChanged() 信号。

GUI 程序设计的主要内容就是对界面上各组件的信号的响应,只需要知道什么情况下发射哪些信号,合理地去响应和处理这些信号就可以了。

槽(Slot)

就是对信号响应的函数。槽就是一个函数,与一般的C++函数是一样的,可以定义在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。

信号与槽关联是用 QObject::connect() 函数实现的,其基本格式是:

QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));

参数1、信号的发送者

参数2、发送的信号

参数3、信号的接收者

参数4、处理函数(槽函数)

案例实操:

现在我们点击关闭窗口整个按钮,我们是,没有任何反应的,我现在在要想点击该按钮实现关闭窗口的功能。那么就得给他们之间建立信号与槽的联系

理解:按钮接收一个鼠标单击的信号,马上,窗口就执行关闭函数。

  1. 首先我们查看按钮QPushButton可以接收哪些信号?在帮助文档索引中搜索QPushButton

 

在QPushButton类中是找不到Signals的,要在他的父类QAbstractButton中查看。

  1. 可以看到他可以接收这4种信号。

我们现在就先尝试使用第一个,单击信号。实现单击按钮关闭窗口

  1. 关闭谁呢,关闭窗口,哪个窗口呢?我们自己新建的Widget窗口,那么我们有实现它的关闭吗?并没有,那么我们需要自己先实现一个吗?不需要,我们可以看

Widget类,其实是QDialog的子类,而QDialog又是QWidget的子类,所以我们去帮助文档看看QWidget,直接在Public Slots种找,

第一个就是close()函数,应该就是关闭窗体的实现,也可以点进去看看。

  1. 现在我们实现信号槽的4个要素,就已经凑齐了,信号发送者是按钮我们new的是btn,发送的信号是clicked单击信号,信号接收者是this,就是本窗口嘛,槽函数是close,现在就好说了,可以让他们建立联系。
  2. 实现信号和槽的机制.
    a.首先我们在窗口中添加按钮
    //窗口头文件中田间
    #include "qpushbutton.h"
    
    //窗口头文件中添加按钮
    private:
        Ui::Widget *ui;
         QPushButton* btn;
    
    //窗口.cpp中添加
     btn=new QPushButton;
         btn->setText("关闭窗口");
         btn->setParent(this);//选择父对象
         btn->resize(120,70);//
         btn->move(100,180);
         connect(btn,&QPushButton::clicked,this,&QWidget::close);//clicked是信号,click是槽,注意区分
     //注意,在信号函数,和槽函数前需要加&号。

  3. 编译,执行,点击“关闭窗口”按钮便可以关闭窗口。
  4. 总结:将本来没有连接的两个对象,连接在一起。本来点击按钮,跟关闭窗口没有联系,我们可以同connect让他们建立起联系。          

2、Qt中自定义信号和槽函数

那么我们是否可以自定以信号和槽函数呢?答案是:按当当然是可以的。

在这个的基础上,我们先设定一个需求:

土豆发向苹果,发送信号,苹果接收信号,并回应:土豆收到。

这里面有两个对象,一个土豆,一个番茄,我们将使用自定义的信号和槽将他们联系起来。

  1. 首先新建两个类,一个,一个Vegetables,一个Fruits。

以Vegetables为例 右击项目>add new

选择C++Class,选择。

类名自定义Vegetables,选择QObject为基类是为了将此类加入qt children中,而QObject是最基本的基类。以同样的方式创建Fruits类。

  1. 在Vegetables类的头文件中加入自定义信号
#ifndef FRUITS_H
#define FRUITS_H

#include <QObject>

class Fruits : public QObject
{
    Q_OBJECT
public:
    explicit Fruits(QObject *parent = nullptr);

signals:
    添加代码
    void send();//信号函数返回值为void ,且不需要定义
};

#endif // FRUITS_H
  1. 在Fruits类的头文件和源文件中添加自定义槽函数的定义和实现
#ifndef VEGETABLES_H
#define VEGETABLES_H

#include <QObject>

class Vegetables : public QObject
{
    Q_OBJECT
public:
    explicit Vegetables(QObject *parent = nullptr);

signals:
    
public slots:
    //添加槽函数
    void ask();
};

#endif // VEGETABLES_H

 快捷添加定义,高亮后按住Alt+Enterf

#include "vegetables.h"
#include<QtDebug>//添加头文件
Vegetables::Vegetables(QObject *parent) : QObject(parent)
{
    
}

void Vegetables::ask()
{
        qDebug()<<"我是土豆,收到收到\n";//收到single 后输出到输出栏
}
  1. 在widget.h中的widget类中添加两个成员,Fruits对象pg(苹果),Vegetables对象td(小姐姐)两个指针。
两个头文件
#include "fruits.h"
#include "vegetables.h"

私有类中
private:
    Ui::Widget *ui;
    QPushButton* btn;
    Fruits *pg;
    Vegetables *td;
  1. 在widget.cpp中new出对象并添加连接。
   pg=new Fruits(this);
     td=new Vegetables(this);
     //connect 联立
     connect(pg,&Fruits::send,td,&Vegetables::ask);//注意此处传入的是函数指针,所以不需要打括号
     pg->send();
  1. 运行程序,程序在表白函数中发送single,接收者收到信息并执行相应的槽函数。

运行结果:打印出了槽函数中的信息。实现了自定义的信号和槽函数

 如果显示含有换行符,这是由于QT编码问题,把槽函数的输出文字中的中文符号换成英文符号就好。

  1. 总结:自定义信号和槽的区别,信号和槽都为void类型,信号只需要定义,不需要实现,而槽函数既需要定义,也需要实现信号和槽都可以有参数也都可以重载。emit是出发信号的标志,可要可不要。

                                                                                                                                                                                                                           

3、自定义信号带参数重载问题

自定义信号带参数重载问题

上节课我们讲到,信号和槽都是可以带参数重载的,选择的我们就来学习带参数重载后的问题,及解决的办法。

首先看需求,苹果发送信号成功后,苹果说“开始执行任务”,土豆收到信号后就回复“土豆收到”,这之间的话,就通过信号的参数来传递。

好,还是来到我们上节课的项目。

  1. 在fruits.h的signals下重载send函数,带一个QString参数,就是这个传过去一句话,女孩也说这句话。
    signals:
        //添加代码
        void send();//信号函数返回值为void ,且不需要定义
        void send(QString);//重载一个含有QString的参数

记住,这个信号只需要定义,不需要实现,只要知道定义了这么一个带一个参数的信号就行了。触发这个信号,还需要一个QString的参数。

  1. 在vegetables.cpp也重载一个带参数的回应的槽函数
    public slots:
        //添加槽函数
        void ask();
        void ask(QString);
    void Vegetables::ask(QString)
    {
        qDebug()<<str;
        qDebug()<<"土豆收到,保证完成任务";
    }

    添加连接

         //在weight.cpp中添加
        void(Fruits::*pSent)(QString)=&Fruits::send;
         void(Vegetables::*Ack)(QString)=&Vegetables::ask;
         connect(pg,pSent,td,Ack);
         pg->send("土豆执行任务");

        执行结果:

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

这个就不用实例了,我们的按钮和窗口上的xx都可以关闭窗口。

信号和槽的参数必须一一对应。

信号的发送什么,槽就接收什么,类型必须一致。但信号的参数个数可以多余槽的参数的个数,但前面相同数量的参数类型必须一一对应。反之则不可以。

今天的分享就到这里来,希望大家看完之后能够准确的掌握QT信号和槽,第一次写博客,希望大家多多支持,给一个免费的关注和赞,后期我会在CSDN分享QT,MFC,MYSQL,C++重难点和数据库方面的学习经验,希望大家多多支持!!!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一次吃透Qt中信号与槽(包含信号与槽的使用,自定义以及重构示例,建议收藏) 的相关文章

  • 结构化绑定中缺少类型信息

    我刚刚了解了 C 中的结构化绑定 但有一件事我不喜欢 auto x y some func is that auto正在隐藏类型x and y 我得抬头看看some func的声明来了解类型x and y 或者 我可以写 T1 x T2 y
  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • 为什么 isnormal() 说一个值是正常的,而实际上不是?

    include
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么

随机推荐

  • 软件测试—第六章白盒测试基本路径测试法

    一 基本路径法 1 为什么使用基本路径法 一是降低了测试用例设计的难度 只要搞清了各种流程 就可以设计出高质量的测试用例来 而不用太多测试方面的经验 二是在测试时间较紧的情况下 可以有的放矢的选择测试用例 而不用完全根据经验来取舍 2 什么
  • 如何设置当我们点击鼠标右键时,可以有新建Typora的选项

    最近研究了一下注册表 感觉这个东西还是挺有意思的 今天周末放假 打算写一点日记 当然是不发表的那种 然后我果断打开了Typora 不过由于好久没用Typora了 我忘记把他放在哪里了 找了一段时间终于找到了 我突然想到 为什么不把Typor
  • 目标检测算法之YOLOV3

    本博客中YOLO系列均为个人理解笔记 欢迎评论指出理解有误或者要讨论的地方 YOLOV3模型相比于v2来说 实质性的改进并不大 更多的是一些技术的堆叠 其并不像yolov2对于v1一样 由巨大的改变和提升 其相对于yolov2 改变在于 1
  • Java并发(多线程和锁机制)

    part 01 Java线程 1 进程和线程的区别 进程是操作系统进行资源分配的最小单位 线程是操作系统进行任务分配的最小单位 一个进程可以有多个线程 2 Java开启线程的方式 继承Tread类 重写run方法 实现Runnable接口
  • 红日安全靶机实战(一)

    0x01 入侵web服务器 0x 1 1 信息收集 首先使用 nmap 来扫描ip 段存活的主机 nmap sn 192 168 127 0 24 这里网上有的用 netdiscover 来扫描 其实和 nmap sn 扫描原理是一样的 都
  • .secret勒索病毒数据恢复

    导言 在数字时代 随着科技的迅猛发展 我们的生活更加便捷 但也引发了一系列新的威胁 其中之一就是勒索软件 而 secret 勒索病毒 则是这个威胁中的一颗明亮而又毒辣的星 91数据恢复本文将带您深入了解 secre 勒索病毒的特点 并探讨如
  • Image Sensor的FSIN/VSYNC

    本文介绍Image Sensor的FSIN VSYNC 产品开发过程 比如3D成像 中 有时会遇到需要2个及以上的Image Sensor同步采集 因此 Image Sensor厂家对于他们的产品都提供了同步功能 也就是我们经常所见的FSI
  • 学习Vue基础的分享

    Vue是一个前端框架 所以就有自己特定的语法 所以在这里列出学到的基础语法作用 基础模板参考 div h1 testName a baidu a h1 div
  • c语言ofstream未定义标识符,关于c++:c中ifstream及ofstream超详细说明

    前文说过 ifstream是继承于istream ofstream是继承于ostream fstream是继承于iostream类 而他们应用的缓冲区类是filebuf 对于这些类之间的关系 有趣味能够去查看我之前的文章 c 规范输入输出流
  • httpclient错误

    Caused by org apache http ProtocolException Target host is not specified at org apache http impl conn DefaultRoutePlanne
  • 用python实现计算器

    上次我用我学习的python做一个简易的计算器 我对计算器进行了 更改优化 变成了一个真正的计算器 实现流程 1 计算机布局 2 计算机执行 首先导入模块 Tkinter 作为 Python GUI 开发工具之一 它具有 GUI 软件包的必
  • 技术大佬和普通程序员改bug的区别!

    阅读本文大概需要2min 文 强哥 未经授权禁止转载 在我这么多年的工作生涯里 难免遇到那些工作糊弄的开发同事 随意编程的实习生 不够细致的测试 缺乏专业度的产品 产品的体验 取决于多个环节的把控 但很多情况下 由于bug严重影响体验 或者
  • 【原创】遇到 ORACLE 错误 1017

    1 错误描述 expdp sys leixiao orcl1 schemas sys directory DATA PUMP DIR dumpfile expdp test1 dmp logfile expdp test1 log 以sys
  • 做影视剪辑短视频,新手小白一个月赚5000多,用点心你也可以

    大周有一个学员把短视频当自己兴趣爱好 空余时间做二次剪辑 谁想到一个月多赚了5000多 他在一家私企上班 工作还算稳定 每天朝九晚五的工作 他不想就这样日复一日平淡的过下去 找到了大周 开始了自己短视频之旅 他这个人比较腼腆 本人出镜拍视频
  • 解决Android通过chrome://inspect/调试WebView出现 HTTP/1.1 404 Not Found 的问题

    问题描述 无论是调试Web页面还是调试Hybrid混合应用 只要是调试Android的webview 都需要使用Chrome inspect进行调试 但是国内开发者会出现404 Not Found错误 原因解析 国内网络无法访问 https
  • Java中九大内置对象

    1 Request对象 该对象封装了用户提交的信息 通过调用该对象相应的方法可以获取封装的信息 即使用该对象可以获取用户提交的信息 当Request对象获取客户提交的汉字字符时 会出现乱码问题 必须进行特殊处理 首先 将获取的字符串用ISO
  • 全国计算机等级考试题库二级C操作题100套(第91套)

    第91套 函数fun的功能是 计算请在程序的下划线处填入正确的内容并把下划线删除 使程序得出正确的结果 注意 源程序存放在考生文件夹下的BLANK1 C中 不得增行或删行 也不得更改程序的结构 给定源程序 include
  • Spring Cloud 2.2.2 源码之三十九nacos配置动态刷新原理一

    Spring Cloud 2 2 2 源码之三十九nacos配置动态刷新原理一 RefreshScope注解类实例化基本流程 nacos如何通过RefreshScope注解进行属性刷新 RefreshEventListener的handle
  • Selenium安装及环境配置

    目录 一 Selenium 简介 1 组件 2 特点 二 安装Selenium 三 下载对应版本的Chromedriver 1 查看Chrome的版本号 2 下载驱动 chromedriver和配置 3 解压到本地 4 复制文件放入pyth
  • 一次吃透Qt中信号与槽(包含信号与槽的使用,自定义以及重构示例,建议收藏)

    1 Qt中信号和槽 信号与槽 信号与槽 Signal Slot 是 Qt 编程的基础 也是 Qt 的一大创新 因为有了信号与槽的编程机制 在 Qt 中处理界面各个组件的交互操作时变得更加直观和简单 它可以让应用程序编程人员把这些互不了解的对