从零开始实现信号槽机制:二

本文深入探讨了Qt的信号槽机制,重点介绍了QMetaObject在信号和槽通信中的关键作用。通过分析元对象系统如何存储和解析QObject子类的元信息,阐述了如何基于这些信息建立和管理连接。文章还提到了 moc 工具生成的metaObject()、qt_metacall()等函数在信号槽机制中的功能,并对比了自定义信号槽机制的优缺点。
摘要由CSDN通过智能技术生成

接上文:从零开始实现信号槽机制:一


关于Qt的信号槽机制,How Qt Signals and Slots Work是一篇特别好的文章,在此对作者表示感谢。

好了,是时候写段Qt代码看看了,这是一段典型的使用Qt信号槽的代码,因为我们这段代码直接写在main.cpp里面,所以在最后记得加上#include "main.moc":

#include <iostream>
#include <QApplication>
using namespace std;

class Button : public QObject
{
    Q_OBJECT
public:
    void nowClick(bool b) { emit click(b); }
signals:
    void click(bool);
};

class Tv : public QObject
{
    Q_OBJECT
public:
    Tv(int b, int t) : bootTime(b), offTime(t){}
protected slots:
    void onStateChanged(bool b)
    {
        if ( b == true )
            cout << "Tv is being turned on. bootTime is " << bootTime << endl;
        else
            cout << "Tv is being turned off. offTime is " << offTime << endl;
    }
private:
    int bootTime;
    int offTime;
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Button btn;
    Tv tv(10, 20);
    QObject::connect(&btn, SIGNAL(click(bool)), &tv, SLOT(onStateChanged(bool)));
    btn.nowClick(true);

    return a.exec();
}

#include "main.moc"

我们知道Qt源代码在make之前需要先进行一道qmake,而qmake会调用moc.exe这个“元对象编译器”来对包含Q_OBJECT宏的文件进行一个预处理,要弄清Qt的信号槽如何运作,首先我们得知道signals,slots这种不符合C++规范的东西到底被处理成了什么鬼,ok,我们在qobjectdefs.h里面找到它们了:

#define slots
#define signals public // Qt5 中由 protected 改为 public 以支持更多特性
#define emit
#define SLOT(a) "1"#a
#define SIGNAL(a) "2"#a

当然这些定义在某些情况下,比如定义了QT_NO_EMIT时会不同,不过这超出了本文的讨论范围,大家有兴趣可以去读下源码。好的,现在我们知道了,“slots”和“emit”根本就是两个空宏,而signals仅仅是一个public,这样看来,Qt中的信号是个真正的函数无疑,而不是像sigslot中以functor的方式实现。connect函数则是借助SIGNAL和SLOT两个宏为信号和槽函数添加了一个数字并将其转化成字符串,也就是说,上面的main()中的connect实际等价于:

QObject::connect(&btn, "2click(bool)", &tv, "1onStateChanged(bool)");

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值