Qt信号槽源码剖析(一)

大家好,我是IT文艺男,来自一线大厂的一线程序员

大家在使用Qt开发程序时,都知道怎么使用Qt的信号槽,但是Qt信号槽是怎么工作的? 大部分人仍然不知道;也就是说大家只知道怎么使用,却不知道基于什么原理,显然这是不符合深层次发展的;那么今天我就给大家基于Qt源码以及示例代码深度剖析Qt的信号槽机制,一定会对大家有帮助。

基本概念

信号

当对象改变其状态时,信号就由该对象发射 (emit) 出去,而且对象只负责发送信号,它不知道另一端是谁在接收这个信号。

用于接收信号,而且槽只是普通的对象成员函数。一个槽并不知道是否有任何信号与自己相连接。

信号与槽的连接

QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, 
const QObject *receiver, const char *method, 
Qt::ConnectionType type = Qt::AutoConnection)

通过QObject::connect静态函数建立连接;其中sender与receiver是指向对象的指针,signal与method分别通过SIGNAL()与SLOT()宏来进行转换。

元对象编译器

MOC, the Meta Object Compiler。
Qt程序在交由标准编译器(例如MSVC)编译之前,先使用moc分析cpp头文件;如果它发现在一个头文件中包含了Q_OBJECT宏,则会生成另外一个cpp源文件(moc_文件名.cpp),该cpp源文件中包含了Q_OBJECT宏的实现、运行时信息(反射)等。因此Qt程序的完整编译过程为moc->预处理->编译->链接

示例代码

Counter.h文件

#pragma once
#include <QtCore/QObject>

class Counter : public QObject
{
    Q_OBJECT

public:
    Counter();

public:
    int value() const;

public slots:
    void setValue(int value);

signals:
    void valueChanged(int newValue);

private:
    int m_value;
};

Counter.cpp文件

#include "Counter.h"

Counter::Counter():m_value(0)
{
}

int Counter::value() const
{
    return m_value;
}

void Counter::setValue(int value)
{
    if (value != m_value)
    {
        m_value = value;
        emit valueChanged(value);
    }
}

main.cpp文件

#include <QtCore/QCoreApplication>
#include "Counter.h"

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

    Counter counterA;
    Counter counterB;
    QObject::connect(&counterA, SIGNAL(valueChanged(int)), 
    			     &counterB, SLOT(setValue(int)));

    counterA.setValue(10);//counterA.value()=10, counterB.value()=10
    counterB.setValue(20);//counterA.value()=10, counterB.value()=20

    return a.exec();
}

Qt宏

宏定义在qobjectdefs.h文件中(位于QtCore目录)

signals

slots

Q_OBJECT

emit

SIGNAL

SLOT

Qt信号槽源码剖析系列会分拆为多个具体的细致讲解,后续我会一一分析并发布

今天就讲解到这里,更详细的原理分析与讲解,请关注微信公众号(itwenyinan),观看对应的的视频版讲解;谢谢

posted on   IT文艺男  阅读(771)  评论(0编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构

导航

点击右上角即可分享
微信分享提示