Qt 信号与槽实现原理

前言

之前一直停留在使用Qt库的层面,底层的实现也只是了解到一些皮毛而已,现在需要更深的了解它的实现原理,对以后开发会有很大的帮助。

概述

按照我整个深入了解的过程,介绍以下几点主要内容:

  • signals和slots宏
  • MOC 元对象编译器
  • connect连接实现
  • emit发送实现

signals和slots宏

Qt中的signals和slots两个宏的源码:

#     define slots Q_SLOTS
#     define signals Q_SIGNALS

# define Q_SLOTS QT_ANNOTATE_ACCESS_SPECIFIER(qt_slot)
# define Q_SIGNALS public QT_ANNOTATE_ACCESS_SPECIFIER(qt_signal)

可以看到的是这两个宏是没有意义的,那编译的时候怎么去处理呢?如何辨别哪个是信号,哪个是槽函数呢?
带着这些问题查找资料… …

MOC 元对象编译器

标准C++不支持Qt的元对象系统,所以Qt单独提供了MOC工具来解决和C++的兼容问题。
MOC在预处理的时候,读取C++头文件,如果包含Q_OBJECT宏,则将生成一个C++源文件(moc_headername.cpp)。然后将新生成的源文件和其他文件一起进行编译、链接生成程序。
下面列举我创建的简单的Qt项目来看一下moc生成的源文件:
.h:

class QWidgetTest : public QWidget
{
   
    Q_OBJECT

public:
    QWidgetTest(QWidget *parent = Q_NULLPTR);

private:
    Ui::QWidgetTestClass ui;

private:
    int a_;

public:
    void func(int a);

signals:
    void sigTest();

    void sigTttt(int a);

public slots:
    void onTest();

    void onButtonClicked();
};

.cpp:

QWidgetTest::QWidgetTest(QWidget *parent)
    : QWidget(parent)
{
   
    ui.setupUi(this);
	connect(this, SIGNAL(sigTest()), this, SLOT(onTest()));
	connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(onButtonClicked()));
}

void QWidgetTest::func(int a)
{
   

}

void QWidgetTest::onTest()
{
   

}

void QWidgetTest::onButtonClicked()
{
   
	emit sigTest();
}

下面将一部分一部分来介绍MOC预处理生成的moc_QWidgetTest.cpp文件。

// 该结构是存储类中的信号、信号参数、槽函数以及类名
struct qt_meta_stringdata_QWidgetTest_t {
   
    QByteArrayData data[7]; // 有7个信息
    char stringdata0[54];   // 将这些信息按照顺序组成字符串存储
};
/*  
    idx: 信息对应的索引值
    ofs: 在字符串中的偏移量
    len: 偏移长度
*/
#define QT_MOC_LITERAL(idx, ofs, len) \
    Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
    qptrdiff(offsetof(qt_meta_stringdata_QWidgetTest_t, stringdata0) + ofs \
        - idx * sizeof(QByteArrayData)) \
    )
static const qt_meta_stringdata_QWidgetTest_t qt_meta_stringdata_QWidgetTest = {
   
    {
   
QT_MOC_LITERAL(0, 0</
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值