首页 > 其他分享 >【Qt 专栏】信号与槽详解

【Qt 专栏】信号与槽详解

时间:2024-05-01 22:00:12浏览次数:25  
标签:Qt void 详解 专栏 信号 Fruits 参数 Vegetables 函数

5个重要的结论:

1. 对于QT,GUI程序设计的逻辑需要4元素:信号、信号发射者、信号接受者、槽。例如,点击按键后,窗口关闭,这四者的关系如下所示:

 

2. 信号函数返回类型为void,不需要实现。参数类型可以重载。调用时前面可以加 emit(也可不加),表示信号释放。

3. 槽函数返回类型也为void,但一定要实现。参数类型可以重载,并且必须与信号函数一一对应。

4. 槽函数可以单独调用(不是一定要连接信号)。

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

 

 

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、处理函数(槽函数)

 

案例实操:

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

(这部分省略,详细内容请看原文:)

 

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

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

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

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

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

  1. 首先新建两个类,一个,一个Vegetables,一个Fruits。
  2. 类名自定义Vegetables,选择QObject为基类是为了将此类加入qt children中,而QObject是最基本的基类。以同样的方式创建Fruits类。
  3. 在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

4. 在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+Enter。

#include "vegetables.h"
#include<QtDebug>//添加头文件
Vegetables::Vegetables(QObject *parent) : QObject(parent)
{
    
}
 
void Vegetables::ask()
{
        qDebug()<<"我是土豆,收到收到\n";//收到single 后输出到输出栏
}

在widget.h中的widget类中添加两个成员,Fruits对象pg(苹果),Vegetables对象td(小姐姐)两个指针。
两个头文件

#include "fruits.h"
#include "vegetables.h"


 私有类中

private:
    Ui::Widget *ui;
    QPushButton* btn;
    Fruits *pg;
    Vegetables *td;


在widget.cpp中new出对象并添加连接。

pg=new Fruits(this);
td=new Vegetables(this);
//connect 联立
connect(pg,&Fruits::send,td,&Vegetables::ask);//注意此处传入的是函数指针,所以不需要打括号
pg->send();

 

运行程序,程序在表白函数中发送single,接收者收到信息并执行相应的槽函数。

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

 

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

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

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

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

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

 

在fruits.h的signals下重载send函数,带一个QString参数,就是这个传过去一句话(土豆后面也说这句话)。

signals:
    //添加代码
    void send();//信号函数返回值为void ,且不需要定义
    void send(QString);//重载一个含有QString的参数
记住,这个信号只需要定义,不需要实现,只要知道定义了这么一个带一个参数的信号就行了。触发这个信号,还需要一个QString的参数。   在vegetables.cpp也重载一个带参数的回应的槽函数
public slots:
    //添加槽函数
    void ask();
    void ask(QString);

void Vegetables::ask(QString)
{
    qDebug()<<str;
    qDebug()<<"土豆收到,保证完成任务";
}
添加链接:
//在widget.cpp中添加
void(Fruits::*pSent)(QString)=&Fruits::send;
void(Vegetables::*Ack)(QString)=&Vegetables::ask;
connect(pg,pSent,td,Ack);
pg->send("土豆执行任务");

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

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

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

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

 

 

 

参考资料:
                        
原文链接:https://blog.csdn.net/GUOMZH/article/details/129462059

标签:Qt,void,详解,专栏,信号,Fruits,参数,Vegetables,函数
From: https://www.cnblogs.com/FBsharl/p/18169702

相关文章

  • Vue | babel.config.js 配置详解
    babel.config.js 1概述Babel相当于一个中介,一边是用户,另一边是浏览器。这几年,JavaScript发生了很大的变化,许多新特性在很多浏览器里都不支持。Babel的主要作用就是规避这些问题,可以确保JavaScript代码兼容所有的浏览器,比如IE11。2Babel的工作原理Babel使用AST把......
  • 【Qt 专栏】Qt Creator 的 git 配置 & 上传到gitee
    1.进入到Qt项目文件夹内,打开“GitBashHere”2.初始化,在“GitBashHere”中输入  gitinit3.加入所有文件,在“GitBashHere”中输入 gitadd. (需要注意,gitadd后面还有一个点)4.添加备注,gitcommit-m"备份"5.推送本地仓库到gitee(需要事先在gitee上创建好本......
  • 【Qt之JSON文件】QJsonDocument、QJsonObject、QJsonArray等类介绍及使用
    简述Qt5中包含了处理JSON的类,均以QJson开头(例如:QJsonDocument、QJsonArray、QJsonObject),在QtCore模块中,不需要额外引入其它模块。简述常用的JSON库JSON常用类简单的JSON对象简单的JSON数组复杂的JSON更多参考 常用的JSON库json.org 中介绍了......
  • tar命令中--exclude参数详解
    tar命令中--exclude参数详解测试环境:[root@osker/]#uname-r3.10.0-957.el7.x86_64[root@osker/]#cat/etc/redhat-releaseCentOSLinuxrelease7.6.1810(Core)[root@osker/]#treetesttest├──t1│  ├──file1.txt│  ├──file2.txt│  └──file3.t......
  • 无线模块空中唤醒技术原理详解
    空中唤醒功能,英文名称为WakeonRadio(WOR),其原理主要是通过减少接收端射频处于接收状态的时间,而在其余时间使设备处于深度睡眠模式,以此来实现设备功耗的显著降低。这种机制确保了设备在不需要接收数据时保持低功耗状态,而在需要接收数据时能够迅速被唤醒至接收状态。具体来说,空......
  • 详解安卓架构入门
    准备首先进入安卓架构入门的代码仓库:AndroidArchitectureStarterTemplates:https://github.com/android/architecture-templates先看看介绍,简单分析一下:架构入门的模板UI界面非常简陋Navigation导航协程和FlowHilt依赖注入Hilt虚假数据进行UI测试提供了两个......
  • 【网络知识系列】Windows路由表详解
    对于路由器的路由表,大家很熟悉,但是Windows的路由表,了解的人不多。一、Windows路由表条目解释1.1查看网卡信息使用ipconfig/all命令查看网卡信息。1.2查看路由表信息使用routeprint命令查看路由表信息。【活动路由】:ActiveRoutes【网络目标/目标网段】:Networkde......
  • vi编辑器有几种模式?vi编辑器常用命令详解
    vi/vim是工作在字符终端环境下的全屏幕编辑器,因为编辑界面相对比较简单,并没有为用户提供鼠标操作和菜单系统,而是通过按键命令实现相应的编辑和操作功能。在vi编辑界面中可以使用三种不同的工作模式。分别是命令模式(Command mode),编辑模式(Insert mode)和末行模式(Last line mode)。......
  • Qt - QListWidget+QListWidgetItem
    效果:文件结构:qcustomwidget.uiqcustomwidget.h(自定义条目类)#ifndefQCUSTOMWIDGET_H#defineQCUSTOMWIDGET_H#include<QWidget>namespaceUi{classQCustomWidget;}classQCustomWidget:publicQWidget//联系人类{Q_OBJECTpublic:QCustomWidget......
  • 一文详解C++的vector
    vector是C++中使用频率最高的标准库,可以在程序运行时动态改变其大小(例如添加或删除元素),因此又被称为动态数组。使用时,用户无需在意底层内存管理的细节,因为它已经帮你做了这件事情。使用前需要导入<vector>头文件,以下是vector的常见用法:1.创建vectorvector用于保存一组同类型的......