QT_元对象模拟实现

来源:互联网 发布:单片机音乐代码生成器 编辑:程序博客网 时间:2024/06/02 02:02

1、QT元对象说明
QT 元对象Q_OBJECT 类似MFC的类型识别,不同之处在于,类型识别使用MFC的宏定义,依赖语言, 而QT是将元对象通过MOC系统解析成中间文件,模块之间通信,可以包含相应的MOC文件,C++编译MOC,不同的MOC保存自己的QT对象信息.

2、QT信号槽使用原型

class Object{Q_OBJECTpublic:    Object();    virtual ~Object();signals:    void sig1();public slots:    void slot1();};
在实际的使用中 需要解析此文件,特别是要实现Q_OBJECT。在本模拟中我们自己手动解析成最终文件

3、QT元对象模拟实现

1、解析的类moc头文件

#ifndef DB_OBJECT  #define DB_OBJECT  #include<map>#define db_slots#define db_signals protected  #define db_emit  #pragma onceclass QObject;//元对象系统 负责搜集信号与槽的名称struct MetaObject{    //信号组    const char * sig_names;    //槽组    const char * slts_names;    //激活某个信号 ,idx信号索引    static void active(QObject * sender, int idx);};//被连接对象信息struct Connection{    QObject * receiver;    int method;};//保存信号索引 与连接对象映射typedef std::multimap<int, Connection> ConnectionMap;typedef std::multimap<int, Connection>::iterator ConnectionMapIt;class QObject{    static MetaObject meta;    void metacall(int idx);public:    QObject();    //建立连接    static void db_connect(QObject*, const char*, QObject*, const char*);    //测试用    void testSignal();db_signals:    void sig1();    public db_slots:    void slot1();    friend class MetaObject;private:    ConnectionMap connections;};#endif  

2、解析的类moc.CPP文件

#include "stdafx.h"#include "QObject.h"static const char sig_names[] = "sig1\n";static const char slts_names[] = "slot1\n";MetaObject QObject::meta = { sig_names, slts_names };QObject::QObject(){}void QObject::sig1(){    MetaObject::active(this, 0);}void QObject::slot1(){    printf("hello dbzhang800!");}//激活信号void QObject::metacall(int idx){    switch (idx) {    case 0:        slot1();        break;    default:        break;    };}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] == '\n')            return idx;        start = false;        if (*pos == '/n') {            idx++;            start = true;        }        pos++;    }    return -1;}void QObject::db_connect(QObject* sender, const char* sig, QObject* 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 QObject::testSignal(){    db_emit sig1();}void MetaObject::active(QObject* 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);    }}

3、模拟使用

// TestQobject.cpp : 定义控制台应用程序的入口点。//模拟QT元对象系统//参照Qt信号与槽实现原理  http://blog.csdn.net/fuyunzhishang1/article/details/48345381#include "stdafx.h"#include "QObject.h"#include <iostream>using namespace  std;//QObject 为解析后的文件,Qt的元对象系统预处理器叫做moc,我们自己手动解析了,/* 在QT类似如下使用class Object{public:    Object();    virtual ~Object();db_signals:    void sig1();    public db_slots:    void slot1();};*/# define SLOT(a)     #a# define SIGNAL(a)   #aint _tmain(int argc, _TCHAR* argv[]){    char p[32] = SLOT(QObject);    cout << " cur_value: " << p << endl;    QObject obj1, obj2;    QObject::db_connect(&obj1, SLOT(sig1), &obj2, SIGNAL(slot1));    obj1.testSignal();    getchar();    return 0;}

注:以上代码引用http://blog.csdn.net/fuyunzhishang1/article/details/48345381

0 0
原创粉丝点击