Qt如何实现信号和插槽?

ant*_*ton 15 qt signals-slots

有人能向我解释Qt信号和插槽机制实现的基本思想吗?我想知道所有这些Q_OBJECT宏在"纯C++"中做了什么.这个问题与信号和插槽使用无关.

补充:我知道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);
}
Run Code Online (Sandbox Code Playgroud)

Deb*_*ski 17

关于信号和槽,Q_OBJECT宏将一个虚函数qt_metacall()声明添加到类的声明中,该声明稍后将由它定义moc.(它还添加了一些转换声明,但这里并不重要.)

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

因此,当调用信号时,将执行mocfile中的定义,并QMetaObject::activate()使用信号名称和信号参数调用该定义.activate()然后,该函数确定已建立的连接并获取相应插槽的名称.

然后调用qt_metacall与插槽的名称和给予的信号,并具有较大的帮助下metacall功能代表这个论点switch- case语句来真正的插槽.

由于在C++中没有关于信号和插槽的实际名称的实际运行时信息,正如已经注意到的那样,这些将由SIGNALSLOT宏编码为简单的const char*s(添加"1"或"2")用于区分信号与插槽的名称).

如下定义qobjectdefs.h:

#define SLOT(a)     "1"#a
#define SIGNAL(a)   "2"#a
Run Code Online (Sandbox Code Playgroud)

-

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);
Run Code Online (Sandbox Code Playgroud)

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