Qt信号与槽实现原理
2018-03-14 23:17
387 查看
如果面试有人问你:“QT信号槽的实现实质是什么?”回答:“回调函数”。
http://blog.csdn.net/fuyunzhishang1/article/details/48345381
http://blog.csdn.net/dbzhang800/article/details/6547196
http://blog.csdn.net/bzhxuexi/article/details/45483879
本文使用 ISO C++ 一步一步实现了一个极度简化的信号与槽的系统 (整个程序4个文件共121行代码) 。希望能有助于刚进入Qt世界的C++用户理解Qt最核心的信号槽与元对象系统是如何工作的。
注:Qt5 staging仓库已经引入一种全新的信号与槽的语法:信号可以和普通的函数、类的普通成员函数、lambda函数连接(而不再局限于信号函数和槽函数)
# define SIGNAL(a) "2"#a程序运行时,connect借助两个字符串,即可将信号与槽的关联建立起来,那么,它是如果做到的呢?C++的经验可以告诉我们:
类中应该保存有信号和槽的字符串信息
字符串和信号槽函数要关联
而这,就是通过神奇的元对象系统所实现的(Qt的元对象系统预处理器叫做moc,对文件预处理之后生成一个moc_xxx.cpp文件,然后和其他文件一块编译即可)。接下来,我们不妨尝试用纯C++来实现自己的元对象系统(我们需要有一个自己的预处理器,本文中用双手来代替了,预处理生成的文件是db_xxx.cpp)。继续之前,我们可以先看一下我们最终的类定义class Object
{
DB_OBJECT
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;
};
db_signals
db_slots
规则很简单,将信号和槽的名字提取出来,放到字符串中。可以有多个信号或槽,按顺序"sig1/nsig2/n"
我们可以定义一个类,来存放信息:struct MetaObject
{
const char * sig_names;
const char * slts_names;
};
http://blog.csdn.net/fuyunzhishang1/article/details/48345381
http://blog.csdn.net/dbzhang800/article/details/6547196
http://blog.csdn.net/bzhxuexi/article/details/45483879
本文使用 ISO C++ 一步一步实现了一个极度简化的信号与槽的系统 (整个程序4个文件共121行代码) 。希望能有助于刚进入Qt世界的C++用户理解Qt最核心的信号槽与元对象系统是如何工作的。
注:Qt5 staging仓库已经引入一种全新的信号与槽的语法:信号可以和普通的函数、类的普通成员函数、lambda函数连接(而不再局限于信号函数和槽函数)
Qt信号与槽
GUI程序中,当我们我们点击一个按钮时,我们会期待我们自定义的某个函数被调用。对此,较老的工具集(toolkits)都是通过回调函数(callback)来实现的,Qt的神奇之处就在于,它使用信号(signal)与槽(slot)的技术来取代了回调。在继续之前,我们先看一眼最最常用的 connnect 函数:connect(btn, "2clicked()", this, "1onBtnClicked()")可能你会觉得稍有点眼生,因为为了清楚起见,我没有直接使用大家很熟悉的SIGNAL和SLOT两个宏,宏定义如下:# define SLOT(a) "1"#a# define SIGNAL(a) "2"#a程序运行时,connect借助两个字符串,即可将信号与槽的关联建立起来,那么,它是如果做到的呢?C++的经验可以告诉我们:
类中应该保存有信号和槽的字符串信息
字符串和信号槽函数要关联
而这,就是通过神奇的元对象系统所实现的(Qt的元对象系统预处理器叫做moc,对文件预处理之后生成一个moc_xxx.cpp文件,然后和其他文件一块编译即可)。接下来,我们不妨尝试用纯C++来实现自己的元对象系统(我们需要有一个自己的预处理器,本文中用双手来代替了,预处理生成的文件是db_xxx.cpp)。继续之前,我们可以先看一下我们最终的类定义class Object
{
DB_OBJECT
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;
};
引入元对象系统
首先定义自己的信号和槽为了和普通成员进行区别(以使得预处理器可以知道如何提取信息),我们需要创造一些"关键字"db_signals
db_slots
class Object { public: Object(); virtual ~Object(); db_signals: void sig1(); public db_slots: void slot1(); };通过自己的预处理器,将信息提取取来,放置到一个单独的文件中(比如db_object.cpp):
规则很简单,将信号和槽的名字提取出来,放到字符串中。可以有多个信号或槽,按顺序"sig1/nsig2/n"
static const char sig_names[] = "sig1/n"; static const char slts_names[] = "slot1/n";这些信号和槽的信息,如何才能与类建立关联,如何被访问呢?
我们可以定义一个类,来存放信息:struct MetaObject
{
const char * sig_names;
const char * slts_names;
};
相关文章推荐
- QT中关于信号与槽机制的实现原理
- QT中关于信号与槽机制的实现原理
- qt 信号,槽及反射机制的实现原理 (记录 gui programing with qt 4)
- QT中关于信号与槽机制的实现原理
- QT信号与槽机制的实现原理
- Qt信号与槽实现原理
- QT中关于信号与槽机制的实现原理
- 【QT】深入qt信号与槽实现原理
- QT中关于信号与槽机制的实现原理
- QT中关于信号与槽机制的实现原理
- 零基础学Qt4编程之Qt核心机制与原理之信号与槽
- 【QT】QT信号槽初实现
- Qt触摸屏原理及实现
- 用ISO C++实现自己的信号槽(Qt另类学习)
- Qt实现多线程下的信号与槽通讯
- Qt中Ui名字空间以及setupUi函数的原理和实现 <转>
- Qt中Ui名字空间以及setupUi函数的原理和实现
- Qt核心机制与原理之信号与槽
- Qt中Ui名字空间以及setupUi函数的原理和实现
- Qt之Ui名字空间以及setupUi函数的原理和实现详解