信号与槽简易实现方式

此篇文章借鉴他人供大家学习使用,非原创,在此向原著致谢。
转载自Qt信号与槽实现原理

object.h

#ifndef OBJECT_H
#define OBJECT_H

#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
{
public:
    Object();
    virtual ~Object();

    void testSignal();

    static void db_connect(Object*, const char*, Object*, const char*);

    void metacall(int idx);

db_signals:
    void sig1();

public db_slots:
    void slot1();

    static MetaObject meta;

friend class MetaObject;

private:
    ConnectionMap connections;
};

#endif // OBJECT_H

object.cpp

#include "object.h"

#include <iostream>
#include <QString>
#include <QDebug>

//void getNext(const char *p,int *next)
//{
//    int j,k;
//    next[0]=-1;
//    j=0;
//    k=-1;
//    while(j<strlen(p)-1)
//    {
//        if(k==-1||p[j]==p[k])    //匹配的情况下,p[j]==p[k]
//        {
//            j++;
//            k++;
//            next[j]=k;
//        }
//        else                   //p[j]!=p[k]
//            k=next[k];
//    }
//}

//int find_string(const char *s,const char *p)
//{
//    int next[100];
//    int i,j;
//    i=0;
//    j=0;
//    getNext(p,next);
//    while(i<strlen(s))
//    {
//        if(j==-1||s[i]==p[j])
//        {
//            i++;
//            j++;
//        }
//        else
//        {
//            j=next[j];       //消除了指针i的回溯
//        }
//        if(j==strlen(p))
//            return i-strlen(p);
//    }
//    return -1;
//}


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;
}

Object::Object()
{

}

Object::~Object()
{

}

void Object::testSignal()
{
    db_emit sig1();
}

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()
{
    qDebug() << "hello world!";
}

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);
    }
}

db_object.cpp

#include "object.h"

static const char sig_names[] = "sig1\n";
static const char slts_names[] = "slot1\n";

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;
    };
}

main.cpp

#include <QApplication>

#include "object.h"

#include "Windows.h"
//#include <QDebug>
//#include "stdio.h"
//#include <iostream>

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

    Object obj1, obj2;
    Object::db_connect(&obj1, "sig1", &obj2, "slot1");
    obj1.testSignal();

//    UINT nHash;
//    nHash = (nHash << 5) + nHash + 1;
    qDebug() << nHash;
    printf("%d\n", nHash);
//    std::cout << nHash << std::endl;


    return a.exec();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值