Qt如何實現訊號和插槽?
有人可以向我解釋Qt訊號和插槽機制的基本思路嗎?
我想知道所有這些Q_OBJECT巨集在普通C中做什麼.
這個問題不是關於訊號和插槽的使用.
新增:
我知道Qt使用moc編譯器來將Ct-C轉換成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); }
提前致謝,
安東
關於訊號和插槽,Q_OBJECT巨集將虛擬函式qt_metacall()宣告新增到類的宣告中,該宣告將由moc稍後定義. (它還添加了一些轉換宣告,但這在這裡並不重要.)
然後,moc讀取標頭檔案,當它看到巨集時,它會生成另一個名為moc_headerfilename.cpp的.cpp檔案,其中包含虛擬函式的定義,您可能會問自己為什麼可以提及這些訊號:在標頭檔案沒有正確的定義 – 訊號.
因此,當一個訊號被呼叫時,將執行mocfile中的定義,並使用訊號的名稱和訊號的引數呼叫QMetaObject :: activate().
然後,activate()函式確定已經建立了哪些連線,並獲取相應插槽的名稱.
然後,它會使用插槽名稱和給訊號的引數呼叫qt_metacall,而metacall函式將這個大型switch-case語句的幫助委託給真實插槽.
由於C中沒有關於訊號和時隙的實際名稱的真實執行時間資訊,如已經被注意到的那樣,這些訊號將被SIGNAL和SLOT巨集編碼為簡單的const char *(具有“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);
這是需要提供一些不可能的執行時反射.例如,該函式在ofollow,noindex" target="_blank">
QObject::inherits(const char *)
中呼叫,只需檢查繼承.
http://stackoverflow.com/questions/2008033/how-does-qt-implement-signals-and-slots