#《Qt学习之路》学习之路(1)#Qt5.10软件安装及环境配置->QT信号槽实现方式探究

2018.4.25

最近导师接了一个新项目,需要用到Qt,最近一段时间需要从零学起一个新平台的使用和安装了。

软件安装及环境配置主要参考 Qt5.9.2+VS2015安装配置教程

成功在办公室电脑(WIN10+VS2015+Qt5.10.1)与实验室电脑(WIN7+VS2017+Qt5.10.1)上安装配置成功(貌似匹配有点奇葩,这是历史遗留问题了)。

网上大概翻了一些教程,对比一下发现Qt学习之路2的学习推进方式更适合我一些,为了防止自己遗忘,在这里分享一些学习的要点,我记的知识要点可能偏个人一些,大概率思维会比较跳跃,建议参考博主原文和查看官方API理解。


Qt经典信号槽使用方式

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

    Newspaper newspaper("Newspaper A");
    Reader reader;
    QObject::connect(&newspaper, &Newspaper::newPaper.
                     &reader, &Reader::receiveNewspaper);
    newspaper.send();

    return app.exec();
}
最重要的连接函数connect(sender, signal, receiver, slot);。其中,第一个是发出信号的对象,第二个是发送对象发出的信号,第三个是接收信号的对象,第四个是接收对象在接收到信号之后所需要调用的函数。sender 和 receiver 都是QObject指针,signal与slot在使用时最好使用成员函数指针(可以靠编译器帮忙查找函数错误)。当 sender 发出了 signal 信号之后,会自动调用 receiver 的 slot 函数。


QT信号槽实现方式探究

//QT信号槽实现方式探究(类似观察者模式)
//注意事项
//发送者和接收者都需要是 QObject 的子类(当然,槽函数是全局函数、Lambda 表达式等无需接收者的时候除外);
//使用 signals 标记信号函数,信号是一个函数声明,返回 void,不需要实现函数代码;
//槽函数是普通的成员函数,作为成员函数,会受到 public、private、protected 的影响;
//使用 emit 在恰当的位置发送信号;
//使用 QObject::connect() 函数连接信号和槽。

#include <QObject>

//newspaper.h;
class Newspaper: public QObject
{
    //凡是 QObject 类(不管是直接子类还是间接子类),都应该在第一行代码写上 Q_OBJECT
    Q_OBJECT
public:
    Newspaper(const QString & name)
        :m_name(name)
    {
    }

    void send(){
        //emit 的含义是发出,实际的报纸名字 m_name 当做参数传给这个信号
        emit newPaper(m_name);
    }

signals:
    //该类的信号
    void newPaper(const QString &name);

private:
    QString m_name;
};


//reader.h
#include <QObject>
#include <QDebug>

class Reader:public QObject{
    Q_OBJECT
public:
    Reader(){}

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

//main.cpp
#include <QCoreApplication>
//#include "newspaper.h";
//#include "reader.h";

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

    Newspaper newspaper("Newspaper A");
    Reader reader;
    QObject::connect(&newspaper, &Newspaper::newPaper.
                     &reader, &Reader::receiveNewspaper);
    newspaper.send();

    return app.exec();
}

只有继承了QObject类的类,才具有使用信号槽的能力。凡是QObject类(不管是直接子类还是间接子类),都应该在第一行代码写上Q_OBJECT。不管是不是使用信号槽,都应该添加Q_OBJECT,且应该放在头文件中。这个宏将由moc做特殊处理展开,将为我们的类提供信号槽机制、国际化机制以及 Qt 提供的不基于 C++ RTTI 的反射能力。

emit 是 Qt 对 C++ 的扩展,是一个关键字(其实也是一个宏),emit 的含义是发出信号。

自定义信号槽需要注意的事项:
1. 发送者和接收者都需要是QObject的子类(当然,槽函数是全局函数、Lambda 表达式等无需接收者的时候除外);
2. 使用 signals 标记信号函数,信号是一个函数声明,返回 void,不需要实现函数代码;
3. 槽函数是普通的成员函数,作为成员函数,会受到 public、private、protected 的影响;
4. 使用 emit 在恰当的位置发送信号;
5. 使用QObject::connect()函数连接信号和槽;
6. 相互绑定时防止发生无限循环。




猜你喜欢

转载自blog.csdn.net/qq_20304723/article/details/80075660
今日推荐