QT Core | 信号槽03 - 自定义信号与槽

本文通过一个QT控制台项目实例,详细讲解了如何创建类、编写代码并利用信号槽机制进行通信。文中介绍了新建QT项目的步骤,创建Newspaper和Reader类,以及如何在main.cpp中连接信号和槽,实现了一个信号触发两个槽的同步操作。重点在于理解信号与槽的本质和使用方法,以及它们在模块化程序设计中的作用。
摘要由CSDN通过智能技术生成

一、前言


记住,信号与槽本质都是返回类型为void的函数。
QT提供的信号与槽,是QT的核心功能之一。它们跟QT的GUI没有关系,所以编写没有GUI的QT应用程序也是可以使用QT的信号与槽的。值得注意的是,使用QT编写漂亮且模块化的应用程序必须要使用信号与槽。
只要用户编写的类继承QObject类,就能使用信号与槽的功能。QT的signal(信号)与slot(槽)本质就是一个函数,且不需要返回值,意识到这一点非常重要。从下图可以看到,Object1的signal1可以同步(触发)Object2的slot1与slot2。Object1的signal2可以同步(触发)Object4的slot1。所以,QT的信号与槽有利于程序的模块化。
在这里插入图片描述
请同学们务必学习豆子的博客上的《QT学习之路2(5)自定义信号槽》,才能看懂以下的内容。博客地址:https://www.devbean.net/2012/08/qt-study-road-2-custom-signal-slot/
我的QT版本:
在这里插入图片描述
QT工程:
链接:https://pan.baidu.com/s/1lqoq0XhUgE1De8Ok1FPTHQ
提取码:s6yp

二、新建一个QT控制台项目


2.1、New File or Project

在这里插入图片描述

2.2、Project Location

在这里插入图片描述

2.3、Define Build System

在这里插入图片描述

2.4、Kit Selection

在这里插入图片描述

2.5、Project Application

在这里插入图片描述

2.6、生成的项目

在这里插入图片描述

三、创建类


3.1、创建Newspaper类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2、创建Reader类

以同样的方式创建Reader类
在这里插入图片描述
在这里插入图片描述

四、编写代码


4.0、pro文件

QT创建的项目默认是C++11版本,目前大部分的C++教程都是使用C++14版本,所以我决定使用C++14版本。值得注意的是,C++版本越高并不代表越好,追求稳定才是硬道理。

在这里插入图片描述

4.1、newspaper.h

#ifndef NEWSPAPER_H
#define NEWSPAPER_H

#include <QObject>

class Newspaper : public QObject
{
    Q_OBJECT
public:
    explicit Newspaper(QObject *parent = nullptr);
    Newspaper(const QString& name);
    void send() const;                         /* 用于发送已有的信号 */

signals:
    /* 1、信号就是一个一个函数名,信号不需要返回变量,所以都是void.
     * 2、信号的函数不需要实现,因为QT的moc帮我们实现好了.
     * 3、信号的内容是什么?其实就是函数的入口参数.
     */
    void newPaper(const QString& name) const;   /* 声明一个信号(newPaper) */

public slots:

private:
   QString m_name;

};

#endif // NEWSPAPER_H

4.2、newspaper.cpp

#include "newspaper.h"

Newspaper::Newspaper(QObject *parent) : QObject(parent)
{

}

Newspaper::Newspaper(const QString& name):
    m_name(name)
{

}

/* 该函数用于发送已经定义好的信号 */
void Newspaper::send() const
{
    emit newPaper(m_name); //发送newPaper信号,该信号的内容是m_name
}

4.3、reader.h

#ifndef READER_H
#define READER_H

#include <QObject>
#include <QDebug>
class Reader : public QObject
{
    Q_OBJECT
public:
    explicit Reader(QObject *parent = nullptr);

signals:

public slots:
    void receiveNewspaper(const QString& name) const;
};

#endif // READER_H

4.4、reader.cpp

#include "reader.h"

Reader::Reader(QObject *parent) : QObject(parent)
{

}

void Reader::receiveNewspaper(const QString& name) const
{
    qDebug() << "Receives Newspaper: " << name;
}

4.5、main.cpp

#include <QCoreApplication>

#include "newspaper.h"
#include "reader.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Newspaper newspaper("Newspaper A");  /* 创建newspaper对象 */
    Reader reader;                       /* 创建reader对象 */

    /* 建立信号与槽 */
    QObject::connect(&newspaper,&Newspaper::newPaper,
                     &reader,   &Reader::receiveNewspaper);

    newspaper.send();  /* 调用信号,并触发对应的槽 */

    return a.exec();
}

五、Debug


编译,运行。控制台输出一条字符串。
在这里插入图片描述
返回上面的代码可以了解到,newspaper对象不具备打印字符串到控制台的功能,只有reader对象才能往控制台输出字符串。所以,上面的字符串肯定是reader对象得槽函数打印出来的。

六、用一个信号同步(触发)两个槽


上面的例子是1个信号同步一个槽,根据官方的介绍,1个信号可以同步多个槽的。所以,这里尝试增加多一个槽。
信号的代码不需要修改,所以newspaper.cpp与newspaper.h不用修改(Newspaper类不用修改)。槽的代码需要修改一下,因为要给reader增加一个类属性my_name。

6.1、reader.h

#ifndef READER_H
#define READER_H

#include <QObject>
#include <QDebug>
class Reader : public QObject
{
    Q_OBJECT
public:
    explicit Reader(QObject *parent = nullptr);
    Reader(const QString& name);  //增加一个构造函数

signals:

public slots:
    void receiveNewspaper(const QString& name) const ;

private:
    QString my_name;  //增加名字
};

#endif // READER_H

6.2、reader.cpp

#include "reader.h"

Reader::Reader(QObject *parent) : QObject(parent)
{

}

Reader::Reader(const QString& name):
    my_name(name)
{

}

void Reader::receiveNewspaper(const QString& name) const
{
    qDebug() <<"I am" << this->my_name << "Receives Newspaper: " << name;
}

6.3、main.cpp

#include <QCoreApplication>
#include "newspaper.h"
#include "reader.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Newspaper newspaper("Newspaper A");  /* 创建newspaper对象 */
    Reader reader_A("reader_A");         /* 创建reader_A对象 */
    Reader reader_B("reader_B");         /* 创建reader_B对象 */

    /* 建立信号与槽 */
    QObject::connect(&newspaper,&Newspaper::newPaper,
                     &reader_A, &Reader::receiveNewspaper);

	  /* 建立信号与槽 */
    QObject::connect(&newspaper,&Newspaper::newPaper,
                     &reader_B, &Reader::receiveNewspaper);

    newspaper.send();  /* 调用信号,并触发对应的槽 */

    return a.exec();
}

6.4、控制台

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wallace Zhang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值