2010-01-05 135 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