Qt中消息的机制原理

参考文章:https://blog.csdn.net/perfectguyipeng/article/details/78082360

原理基础介绍

Qt中通过object类定义了connect函数,在connect函数中实现了将信号与槽函数的对应关系
这种对应关系记录在元对象类中,信号函数的定义由元对象处理器定义,在这一步可以确定信号触发时,槽函数被调用的过程。

主要理解一下几个函数:
static void db_connect(Object*, const char*, Object*, const char*);
void MetaObject::active(Object* sender, int idx)

#ifndef DB_OBJECT  
#define DB_OBJECT  
#include <map>  
# define db_slots  
# define db_signals protected  
# define db_emit  
class Object;
struct MetaObject  //元对象类
{
    const char* sig_names;
    const char* slts_names;
    static void active(Object* sender, int idx);
};
struct Connection 
{
    Object* receiver;
    int method;
};
typedef std::multimap<int, Connection> ConnectionMap;
typedef std::multimap<int, Connection>::iterator ConnectionMapIt;


class Object //object类
{
    static MetaObject meta;
    void metacall(int idx);
public:
    Object();
    virtual ~Object();
    static void db_connect(Object*, const char*, Object*, const char*);

    void testSignal();
db_signals:
    void sig1();
    public db_slots:
    void slot1();
    friend class MetaObject;
private:
    ConnectionMap connections;
};
#endif 


#include "object.h"

#include <stdio.h>  
#include <string.h>   
Object::Object()
{
}
Object::~Object()
{
}
static int find_string(const char* str, const char* substr)
{
    if (strlen(str) < strlen(substr))
        return -1;
    int idx = 0;
    int len = strlen(substr);
    bool start = true;
    const char* pos = str;
    while (*pos) {
        if (start
            && (!strncmp(pos, substr, len))
            && (pos[len] == '\0'))
        {
            return idx;
        }
     
        start = false;
        if (*pos == '\0') {
            idx++;
            start = true;
        }
        pos++;
    }
    return -1;
}
void Object::db_connect(Object* sender, const char* sig, Object* receiver, const char* slt)
{
    int sig_idx = find_string(sender->meta.sig_names, sig);
    int slt_idx = find_string(receiver->meta.slts_names, slt);
    if (sig_idx == -1 || slt_idx == -1) {
        perror("signal or slot not found!");
    }
    else {
        Connection c = { receiver, slt_idx };
        sender->connections.insert(std::pair<int, Connection>(sig_idx, c));
    }
}
void Object::slot1()
{
    printf("hello dbzhang800!");
}
void MetaObject::active(Object* sender, int idx)
{
    ConnectionMapIt it;
    std::pair<ConnectionMapIt, ConnectionMapIt> ret;
    ret = sender->connections.equal_range(idx);
    for (it = ret.first; it != ret.second; ++it) {
        Connection c = (*it).second;
        c.receiver->metacall(c.method);
    }
}
void Object::testSignal()
{
    db_emit sig1();
}
#include "object.h"  
static const char sig_names[] = "sig1";
static const char slts_names[] = "slot1";
MetaObject Object::meta = { sig_names, slts_names };

// *** 元对象类的实现*********
void Object::sig1()
{
    MetaObject::active(this, 0);
}
void Object::metacall(int idx) 
{
    switch (idx) {
    case 0:
        slot1();
        break;
    default:
        break;
    };
}
#include "object.h"  
int main()
{
    Object obj1, obj2;
    Object::db_connect(&obj1, "sig1", &obj2, "slot1");
    obj1.testSignal();
    return 0;;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt的信号与槽机制是其最重要的特性之一,它提供了一种灵活而高效的通信方式。信号与槽可以在不同对象之间进行通信,使得这些对象能够相互响应和交互。 信号是Qt定义的一种特殊的函数,用于表示某个事件的发生。一个类可以定义一个或多个信号,信号可以在特定的情况下被触发,比如用户点击了一个按钮或者其他的操作发生了一些特定的事件。信号的声明通常位于类的头文件。 槽是一个特殊的成员函数,用于接收信号并对其进行响应。一个类可以定义一个或多个槽函数,用于处理不同的信号。槽函数可以有任意的参数和返回值,但是需要与信号的参数列表和返回值类型匹配。槽函数的声明通常位于类的头文件或者源文件。 信号与槽通过Qt的元对象系统来进行连接。当信号被触发时,与之相关联的槽函数会被调用。信号与槽之间的连接可以通过Qt提供的connect函数来实现,也可以在Qt Creator通过可视化界面来进行连接。 信号与槽之间的连接是动态的,可以在运行时进行创建、修改和断开。这种机制使得对象之间的通信变得非常灵活,能够很好地支持Qt的事件驱动编程模型。 总结起来,Qt的信号与槽机制是一种通过信号和槽函数来实现对象间通信的灵活机制。信号用于表示事件的发生,槽函数用于对信号进行响应。通过Qt的元对象系统,可以在运行时动态地连接、修改和断开信号与槽之间的关联。这种机制使得对象之间的通信变得简单而高效。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值