銆銆鎴戜滑鐭ラ亾Qt浠ヤ粬鐨剆ignal鍜宻lot鏈哄埗鐙澶╀笅銆備絾澶у鍦ㄧ敤鐨勬椂鍊欐湁娌℃湁娉ㄦ剰榪囷紝signal鍜宻lot涔嬮棿鏄紓姝ョ殑錛岃繕鏄悓姝ョ殑鍛紵涓烘鎴戦棶榪囦笉灝戜嬌鐢≦t鐨勯亾鍙嬨傛湁浜鴻鏄悓姝ョ殑錛屾湁浜鴻鏄紓姝ョ殑錛屼篃鏈変漢璇磋鐪嬪綋鏃朵綘鐨勪漢鍝併?( #$%^&*
銆銆涓烘璐亾錛岀壒鍒仛浜嗕互涓嬪嚑涓祴璇曪細
First,鍦╩ain()涓誨嚱鏁伴噷錛岃緗袱涓熀浜嶲Object涓虹埗綾葷殑瀵硅薄a鍜宐錛宎瑙﹀彂signal,b鎺ュ彈signal銆傝鐪嬪叿浣撴渚嬶細
1 class MyTestA : public QObject
2 {
3 Q_OBJECT
4 public:
5 void emitSignal()
6 {
7 signalMyTestA();
8 }
9
10 public slots:
11 void slotMyTestA()
12 {
13 qDebug()<<"slotMyTestA is called.";
14 }
15 signals:
16 void signalMyTestA();
17 };
18
19 class MyTestB : public QObject
20 {
21 Q_OBJECT
22 public slots:
23 void slotMyTestB()
24 {
25 qDebug()<<"slotMyTestB is called.";
26 }
27 signals:
28 void signalMyTestB();
29 };
30
31 int main(int argc, char *argv[])
32 {
33 QApplication app(argc, argv);
34
35 MyTestA a;
36 MyTestB b;
37 QObject::connect(&a,SIGNAL(signalMyTestA()),&b,SLOT(slotMyTestB()));
38
39 a.emitSignal();
40
41 return app.exec();
42 }
鍦╯lotMyTestB鐨勫嚱鏁伴噷鎵撲釜鏂偣錛岀湅涓涓嬭皟鐢ㄥ爢鏍?call stack)銆?/p>
鏄悓姝ヨ皟鐢ㄧ殑錛屾煇浜涢亾鍙嬪紑濮嬫媹鑳″井絎戯紝瀹炶返鍑虹湡鐭ュ晩銆?/p>
姝ゆ椂鍙涓滄柟榛戜簯婊氭粴錛岀數闂浄楦o紝鍙堟湁閬撳弸寮濮嬪害鍔簡銆傜獊鐒朵竴搴﹀姭閬撳弸妯湁鍐峰錛屾嬁璧鋒媯灝樺埛鍒風殑鏀瑰啓浜嗕笂闈㈢殑浠g爜銆傚彧瑙佹閬撳弸鎶奱瀵硅薄鎸埌浜嗕竴涓柊綰跨▼涓紙MyTestC鍒涘緩鐨勶級錛岃宐瀵硅薄浠嶇劧鍦ㄤ富綰跨▼涓傜劧鍚巃瀵硅薄瑙﹀彂淇″彿銆?/p>
class MyTestA : public QObject { Q_OBJECT public: void emitSignal() { signalMyTestA(); } public slots: void slotMyTestA() { qDebug()<<"slotMyTestA is called."; } signals: void signalMyTestA(); }; class MyTestB : public QObject { Q_OBJECT public slots: void slotMyTestB() { qDebug()<<"slotMyTestB is called."; } signals: void signalMyTestB(); }; extern MyTestB *g_pMyTestB; class MyTestC : public QThread { Q_OBJECT public: void run() { MyTestA a; connect(&a,SIGNAL(signalMyTestA()),g_pMyTestB,SLOT(slotMyTestB())); a.emitSignal(); exec(); } public slots: void slotMyTestC() { qDebug()<<"slotMyTestC is called."; } signals: void signalMyTestC(); }; class MyTest : public QDialog { Q_OBJECT public: MyTest(QWidget *parent = 0, Qt::WFlags flags = 0); ~MyTest(); private: Ui::MyTestClass ui; }; //////////////////////////////////////////////// MyTestB *g_pMyTestB = NULL; int main(int argc, char *argv[]) { QApplication app(argc, argv); MyTestB b; g_pMyTestB = &b; MyTestC c; c.start(); return app.exec(); }
璇存椂榪燂紝閭f椂蹇傚湪涓閬撶傳闆峰妶涓嬩箣闄咃紝鎸変笅浜咶5銆傚彧瑙侊紝姝ゆ椂鐨勮皟鐢ㄥ爢鏍堟樉紺?
濂囪抗鍑虹幇浜嗭紝灞呯劧鍙樻垚寮傛璋冪敤浜嗐傚彧瑙佷笢鏂瑰ぉ絀轟竾閬撻噾鍏夊皠涓嬶紝鍦ㄩ樀闃典粰涔愬0涓紝浼犳潵鏈楁湕涔嬪0:"璐亾灝樹簨宸蹭簡錛屽啀鏃犵壍鎸?銆?/p>
闅鵑亾Qt鐪熺殑鏄潬浜哄搧鐨勶紝鎴栬匭t鑾笉鏄篃鏄慨浠欓亾鍙嬶紝涓嶆棩涔熷皢椋炲崌銆?/p>
鍦ㄥ惥絳変紬浜鴻啘鎷滃姞鐤戞儜涔嬫椂錛屽彧瑙侀鍗囧墠杈堬紝鐣欎笅涓鏉″亪璇傚唴浜嬩笉鍐抽棶鐧懼害錛屽浜嬩笉鍐抽棶璋鋒瓕銆?/p>
鍚劇瓑浼椾漢绔嬪埢鎼滃錛屾亶鐒跺ぇ鐗┿?/p>
鍘熸潵signal鍜宻lot鏄紓姝ヨ皟鐢ㄨ繕鏄悓姝ヨ皟鐢紝鍙栧喅浜庡connect鐨勮瀹氥傚叾瀹瀋onnect榪樻湁涓涓弬鏁?Qt::ConnectionType),鏄畠鍐沖畾浜嗘槸鍚屾榪樻槸寮傛銆?/span>浠ヤ笅鏄疌onnectionType鐨勫畾涔?/p>
鍙笉榪囷紝騫沖父瀹冩湁涓涓粯璁ゅ糛t::AutoConnection,鎴戜滑蹇界暐浜嗗畠銆傝繖鏃舵湁閬撳弸闂亾錛屼負浣曞湪AutoConnection妯″紡涓嬶紝鏈夋椂鏄悓姝ワ紝鏈夋椂鏄紓姝ワ紝鑾潪Auto灝辨槸浜哄搧浠e悕璇嶃?/p>
闈炰篃錛屽叾瀹濧uto鏄繖鏍瘋瀹氱殑錛?/p>
褰搒ender鍜宺eceiver鍦ㄥ悓涓綰跨▼鏃訛紝灝辨槸鍚屾妯″紡錛岃屽湪涓嶅悓綰跨▼鏃訛紝鍒欐槸寮傛妯″紡銆?/span>
浼椾漢鐨嗘洶鍠勩?/span>
灝卞湪浼椾漢寮瑰啝鐩稿簡涔嬫椂錛岀獊鐒朵竴閬撶被浼肩溂闀滃彂鍑虹殑瀵掑厜闂繃錛屼竴涓粦褰辨笎娓愭竻鏅頒簡璧鋒潵銆?/span>
浠栧眳鐒跺氨鏄?.................
闈掓槬姘擱┗錛屽崄浜屽勾濡備竴鏃ョ殑鏌崡鍚涳紝浠栨嫑鐗屽紡鐨勭鎬у0闊崇粰浼楅亾鍙嬩竴鏅村ぉ闇歸洺錛?#8220;璇鎬綅浠ヤ負榪欏氨鏄叏閮ㄧ殑鐪熺浉鍚楋紵”
鎺ョ潃浠栧埛鍒風殑鍙堟敼鍐欎簡浠g爜錛屽湪涓葷嚎紼嬩腑鐢熸垚a,b涓や釜瀵硅薄錛岃宎瀵硅薄鍦ㄦ柊綰跨▼錛圡yTestC鍒涘緩鐨勶級涓Е鍙戜俊鍙楓?/span>
class MyTestA : public QObject { Q_OBJECT public: void emitSignal() { signalMyTestA(); } public slots: void slotMyTestA() { qDebug()<<"slotMyTestA is called."; } signals: void signalMyTestA(); }; class MyTestB : public QObject { Q_OBJECT public slots: void slotMyTestB() { qDebug()<<"slotMyTestB is called."; } signals: void signalMyTestB(); }; extern MyTestB *g_pMyTestB; extern MyTestA *g_pMyTestA; class MyTestC : public QThread { Q_OBJECT public: void run() { g_pMyTestA->emitSignal(); exec(); } public slots: void slotMyTestC() { qDebug()<<"slotMyTestC is called."; } signals: void signalMyTestC(); }; ///////////////////////////////////////////// MyTestB *g_pMyTestB = NULL; MyTestA *g_pMyTestA = NULL; int main(int argc, char *argv[]) { QApplication app(argc, argv); MyTestA a; g_pMyTestA = &a; MyTestB b; g_pMyTestB = &b; QObject::connect(&a,SIGNAL(signalMyTestA()),&b,SLOT(slotMyTestB())); MyTestC c; c.start(); return app.exec(); }
鍦ㄤ紬浜虹枒鎯戠殑鐪煎厜涓紝姝ゅ悰娣″畾鐨勬寜涓嬩簡F5銆傚彧瑙佽皟鐢ㄥ爢鏍?call stack)鏄劇ず
浼椾漢鐨嗘儕鍛鹼紝“Impossible”銆俛鍜宐鏄庢槑鏄睘浜庝竴涓嚎紼嬬殑錛屼負浣曚細寮傛璋冪敤銆傛鏃舵垜浠啛鎮夌殑璇綍錛屽張鍦ㄨ寵竟鍥炲搷,鏄?鎴戠浉淇$湡鐩稿彧鏈変竴涓紒錛侊紒"榪欏彞璇濆悧錛烴o錛屽彧瑙佹煰鍗楀悰錛屼紭闆呭湴鎸ヤ簡鎸ユ墜鎸囷紝"Nothing impossible",浠庡彛涓紦緙撴粦鍑恒?/p>
銆備紬浜虹殕鎵戣錛?#8220;鏈夊眮蹇斁”銆?/p>
姝ゆ椂鏌崡鍚涚紦緙撲粠鍙h涓紝鎽稿嚭涓寮犵焊錛屾姏鍚戠┖涓紝鐒跺悗杞韓紱誨幓銆傚彧瑙侀殢椋庨钀界殑綰擱潰涓婇潰鎽樺綍浜嗚繖涔堜竴孌礠t婧愪唬鐮侊紝鍦ˋuto妯″紡涓嬶紝濡傛灉瑕佸悓姝ヨ皟鐢紝涓嶄粎瑕佹眰sender鍜宺eceiver鏄悓涓綰跨▼錛岃屼笖sender瑙﹀彂鐨勬椂鍊欙紝鎵鍦ㄧ殑綰跨▼涔熻鍜宺eceiver涓鑷淬?/p>
// determine if this connection should be sent immediately or // put into the event queue if ((c->connectionType == Qt::AutoConnection && (currentThreadData != sender->d_func()->threadData || receiver->d_func()->threadData != sender->d_func()->threadData)) || (c->connectionType == Qt::QueuedConnection)) { queued_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv); continue; } else if (c->connectionType == Qt::BlockingQueuedConnection) { blocking_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv); continue; }
鎽樿嚜qobject.cpp
z浼椾漢鐨嗘儕錛?strong>鍘熸潵鍦ˋuto妯″紡涓嬶紝濡傛灉sender鐨勮Е鍙戞椂鎵澶勭殑綰跨▼鍜宺eceiver涓嶅悓錛屼篃浼氭槸寮傛璋冪敤銆傛鏃墮亾鍙嬮綈澹板悜鏌崡鍠婇亾“榪欐槸鍏ㄩ儴鐨勭湡鐩鎬簡鍚?#8221;錛熸煰鍗楄漿榪囧ご鏉ョ瑧鑰屼笉璇紝娓愭笎鍙堟秷澶卞湪榛戞殫涓?#8220;鏈夊灝戞棤鑰誨彲浠ラ噸鏉?#8221;婕備笂浜嗕紬浜虹殑蹇冨ご銆傛湜鐫榪滃鐨勯洦鍚庨槼鍏夛紝涓涓ぇ澶х殑闂彿涔熷嚭鐜板湪浼椾漢澶撮《,"Qt浣犲埌搴曟湁澶氭棤鑰伙紵錛燂紵"銆備紬浜哄張闄峰叆浜嗘矇鎬濄?/p>
嬈茬煡鍚庝簨濡備綍錛岃鍚笅鍥炲垎瑙c?/p>
姝ょ瘒宸插湪CNBLOG鍚屾椂鍙戝竷