2010-01-05 138 views
15

有人可以向我解释Qt信号的基本思想& slots机制实现吗? 我想知道所有这些Q_OBJECT宏在“纯C++”中做了什么。 此问题不关于信号&插槽的使用情况。Qt如何实现信号和插槽?

新增: 我知道Qt使用moc编译器以纯C++转换Qt-C++。 但是moc做什么? 我想读“moc_filename.cpp”的文件,但我不知道有什么可以像这样意味着

void *Widget::qt_metacast(const char *_clname) 
{ 
if (!_clname) return 0; 
if (!strcmp(_clname, qt_meta_stringdata_Widget)) 
    return static_cast<void*>(const_cast< Widget*>(this)); 
return QDialog::qt_metacast(_clname); 
} 
+0

dup:http://stackoverflow.com/questions/1406940/how-signal-and-slots-are-implemented-under-the-hood – elcuco 2010-01-05 20:45:22

回答

16

关于信号和插槽,Q_OBJECT宏将虚拟函数qt_metacall()声明添加到类声明中,该声明稍后将由moc定义。 (它也增加了一些声明的转换,但在这里,这不是太重要。)

moc然后读取头文件,当它看到的宏时,它产生另一个.cpp文件名为moc_headerfilename.cpp与定义,虚拟功能和 - 你可能会问自己,为什么你可以在头文件中提到signals:而没有正确定义信号。

因此,当调用一个信号时,将执行mocfile的定义并调用QMetaObject::activate()以及信号的名称和信号的参数。 然后activate()函数计算出哪些连接已建立并获取相应插槽的名称。

然后它调用qt_metacall插槽名称和给出的信号的参数和元调用功能代表这个借助于一个大的switch - case声明真实的插槽。

由于没有关于对信号和槽的实际名称可能在C中没有真正运行时信息++,正如已经注意到了,这些将由SIGNALSLOT宏简单const char* s为单位进行编码(或者用“1”或“2”添加到该名称以区分插槽中的信号)。

正如在qobjectdefs.h定义:

#define SLOT(a)  "1"#a 
#define SIGNAL(a) "2"#a 

-

Q_OBJECT宏所做的就是定义你的目标内部的tr()功能,它可以用来翻译应用程序中的其他事情。

编辑 当你问什么qt_metacast正在做什么。它检查对象是否属于某个类,如果它返回指向它的指针。如果不是,则返回0.

Widget* w = new Widget(); 
Q_ASSERT(w->qt_metacast("Widget") != 0); 
Q_ASSERT(w->qt_metacast("QWidget") != 0); 
Q_ASSERT(w->qt_metacast("QObject") != 0); 
Q_ASSERT(w->qt_metacast("UnrelatedClass") == 0); 

这是需要提供一些运行时反射,否则不可能。例如,该函数在QObject::inherits(const char *)中调用,并简单地检查继承。

+1

另外看看这个博客文章的更多细节:http://woboq.com/blog/how-qt-signals-slots-work.html – guruz 2013-08-12 14:56:48

3

这些宏做“纯C++”,绝对没有 - 他们扩大为空字符串(我认为) 。

QT使用元对象编译器,它为启用Q_OBJECT的类(实现您定义的信号/插槽等)生成C++代码。

您可以在official documentation中了解更多关于它的信息。

+0

确实。事实上,如果你编译代码,你可以看看生成的源代码。 – 2010-01-05 18:29:07

+1

信号和插槽在扩展时需要有小的差异,因为您可以将信号连接到信号,然后不清楚字符串代表什么。 – Debilski 2010-01-05 19:43:50

-1

其基本思想是您可以连接您的对象,以便在信号完成时执行方法(插槽)。

connect(pistol,SIGNAL(sigShoot()),runner,SLOT(slotRun())) 

做上面的连接,当手枪发射信号时,跑垒员将执行其插槽。

为此,您必须在各自的类中声明您的信号和插槽。

是基本的想法。

祝你好运!

+5

但是OP询问内部实现,而不是如何使用它。 – 2010-05-03 01:20:07

+0

这个想法看起来像dojo处理消息系统的东西。 – 2010-12-22 03:27:28