Qt信号槽机制

C++的RTTI机制功能有限
Qt提供了元对象系统,使用该系统的基类QObject所创建和派生的类,可以再运行期获取该对象的类名、父
类名,成员变量信息,成员函数信息,进而实现信号槽机制。

在这里插入图片描述
在这里插入图片描述
C++ 模拟

类定义文件 object.h

1. #ifndef DB_OBJECT  
2. #define DB_OBJECT  
3. #include <map>  
4. # define db_slots  
5. # define db_signals protected  
6. # define db_emit  
7. class Object;  
8. struct MetaObject  
9. {  
10.     const char * sig_names;  
11.     const char * slts_names;  
12.     static void active(Object * sender, int idx);  
13. };  
14. struct Connection  
15. {  
16.     Object * receiver;  
17.     int method;  
18. };  
19. typedef std::multimap<int, Connection> ConnectionMap;  
20. typedef std::multimap<int, Connection>::iterator ConnectionMapIt;  
21. class Object  
22. {  
23.     static MetaObject meta;  
24.     void metacall(int idx);  
25. public:  
26.     Object();  
27.     virtual ~Object();  
28.     static void db_connect(Object*, const char*, Object*, const char*);  
29.     void testSignal();  
30. db_signals:  
31.     void sig1();  
32. public db_slots:  
33.     void slot1();  
34. friend class MetaObject;  
35. private:  
36.      ConnectionMap connections;  
37. };  
38. #endif  

类实现文件 object.cpp

1. #include <stdio.h>  
2. #include <string.h>  
3. #include "object.h"  
4. Object::Object()  
5. {  
6. }  
7. Object::~Object()  
8. {  
9. }  
10. static int find_string(const char * str, const char * substr)  
11. {  
12.     if (strlen(str) < strlen(substr))  
13.         return -1;  
14.     int idx = 0;  
15.     int len = strlen(substr);  
16.     bool start = true;  
17.     const char * pos = str;  
18.     while (*pos) {  
19.         if (start && !strncmp(pos, substr, len) && pos[len]=='/n')  
20.             return idx;  
21.         start = false;  
22.         if (*pos == '/n') {  
23.             idx++;  
24.             start = true;  
25.         }  
26.         pos++;  
27.     }  
28.     return -1;  
29. }  
30. void Object::db_connect(Object* sender, const char* sig, Object* receiver, const char* slt)  
31. {  
32.     int sig_idx = find_string(sender->meta.sig_names, sig);  
33.     int slt_idx = find_string(receiver->meta.slts_names, slt);  
34.     if (sig_idx == -1 || slt_idx == -1) {  
35.         perror("signal or slot not found!");  
36.     } else {  
37.         Connection c = {receiver, slt_idx};  
38.         sender->connections.insert(std::pair<int, Connection>(sig_idx, c));  
39.     }  
40. }  
41. void Object::slot1()  
42. {  
43.     printf("hello dbzhang800!");  
44. }  
45. void MetaObject::active(Object* sender, int idx)  
46. {  
47.     ConnectionMapIt it;  
48.     std::pair<ConnectionMapIt, ConnectionMapIt> ret;  
49.     ret = sender->connections.equal_range(idx);  
50.     for (it=ret.first; it!=ret.second; ++it) {  
51.         Connection c = (*it).second;  
52.         c.receiver->metacall(c.method);  
53.     }  
54. }  

55. void Object::testSignal()  
56. {  
57.     db_emit sig1();  
58. }  

自己的预处理需要生成这样一个文件 db_object.cpp

1. #include "object.h"  
2. static const char sig_names[] = "sig1/n";  
3. static const char slts_names[] = "slot1/n";  
4. MetaObject Object::meta = {sig_names, slts_names};  
5. void Object::sig1()  
6. {  
7.     MetaObject::active(this, 0);  
8. }  
9. void Object::metacall(int idx)  
10. {  
11.     switch (idx) {  
12.         case 0:  
13.             slot1();  
14.             break;  
15.         default:  
16.             break;  
17.     };  
18. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值