在QT開始,第二部分 - 信號,槽和定時器
在這篇文章中我也跟著用遊戲來彌補對 QT初學者的小教程。 這一次,我將展示如何創建自己的信號和槽,以及如何處理計時器。
源代碼可以在此鏈接 。
示例程序是一個計時器,將使用類QTime ,對QT的主要類別之一,而且會告訴你風格的液晶顯示器使用計算器類QLCDNumber 。
QT和計時器
QT中的最基本的支持定時器是從QObject類,它提供的方法可用的QObject::的startTime()和QObject的::KillTimer() 。 第一個方法返回一個唯一的ID,第二個計時器結束時通過這個 ID的定時器。
對於這個工作,但是,一段代碼,使用這一機制必須在一個“事件循環”。 一旦啟動計時器不時它(超時)作出申請Dispater QTimerEvent ,擾亂了正常的程序流,直到事件被處理。
最大超時沒有定義,它可以創建具有多年超時定時器,但是,最短時間可以從系統到系統。 在Windows Vista的最低定時器為 10毫秒,而這是在Linux 2.6.x的配置(默認為 4毫秒)。 在QT會盡量提供所有事件,要求,但如果系統不會讓它降“盈餘”。
定時器也可用於線程,但你必須尊重一個事件循環內被條件。 主題值得另一篇文章中,一如既往...
類QTime實現定時器較高的水平,使某些功能。 一個是QTime:singleShot() ,其中一次火災事件。
閱讀大量文件和重複,枯燥,但相信我,你會節省很多的QDorDeCabeca ...
更多關於信號和槽
信號和槽用於對象之間,對 QT的一個通訊中心焦點。 在這個系統中,而不是實現回調來處理事件,我們使用了連接信號槽的概念,使得編程更加直觀。
信號和槽是由類處理方法元對象編譯器(MOC)前的源代碼進行編譯。 他們不屬於標準 C + +,所以fazum商務部解析源代碼,並生成可編譯部分的特別聲明。
通過運行在任何類來實現信號和槽,商務部命令的源代碼的某些量產生。 隨著該方案的使用qmake的 ,商務部到程序調用到Makefile文件,使它透明的程序員。
對於一個類可以實現信號和槽,它需要訪問的元對象系統 。 因此,應該從類繼承QObject的和它的子類,並需要有宏Q_OBJECT在其隱私聲明面積。 完成了準備工作,標誌中聲明一節“信號”中的部分和槽“[公眾|保護|私人]槽”。
後宣布槽,然後像其他常見的方法定義,可以明確地稱為像任何其他。 種種跡象都已經多了幾分細膩,只有永遠宣布,由程序員定義。 究其原因? 而在試圖建立結束消息:
TMP / moc_mydisplay.o:在函數'MyDisplay:signalPlay()“: 〜/秒錶 / TMP / moc_mydisplay.cpp:89:`MyDisplay多個定義:signalPlay() TMP / mydisplay.o:〜/秒錶 / mydisplay.cpp:169:首先這裡定義 collect2:ld的退出狀態返回1 製作:** [秒錶]錯誤 1
裡面的文件生成moc_mydisplay.cpp下面的代碼:
/ /信號0 signalPlay ( ) 無效 MyDisplay:signalPlay() { activate ( this , & staticMetaObject , 0 , 0 ) ; QMetaObject:: 激活 (這一點,與staticMetaObject,0,0); }
是的,建設部生成一個與所謂的QT元方法的定義信號。 因此,界定在QT信號的身體是非法的,將通過重新生成方法的編譯錯誤。 讓 MOC利用了你的信號實施護理。
連接
這已經不是剛剛設置好的信號和槽。 你必須定義他們將如何相互作用的。 要做到這一點的方法是通過連接通過連接(它們)方法在每一個繼承人存在QObject的 。 這建設部將實施的信號,以便向它在給(S)插槽(S)連接(S)用同樣的參數調用的結果調用。
根據連接,甚至可以返回信號的要求回最後一個插槽相同的值。 請注意,這不是很安全的連接到多個插槽信號,因此,沒有任何保證的順序命名。
一個給定的信號可以被連接到第二個信號直接。 一個發射(第一信號),然後相當於一個發射()在第二個信號,因為後創建解脫,在第一次調用的調用結果,第二個步驟,這會導致連接到另一個方法調用等。
連接方式
基本上有三種方式連接信號和槽,如果不正確使用可能是一個可怕的錯誤很難發現的來源。 連接這些形式傳遞給connect()方法的額外的參數。 它們是:
直接連接 :插槽是立即調用信號已經在那裡發出的信號線程發出。 這作為一個直接調用插槽。
排隊連接 :信號發送和到去一個叫槽的QT內部列表,信號立即返回,不管槽被稱為與否。 事件循環將處理該列表,只有後來的插槽是在線程對象所在的插槽調用。
自動連接 :這是默認類型,用於當你不指定連接類型。 這是一個“罪惡的種子” ,它提出了兩種截然不同的行為:如果信號和槽駐留在同一線程上,作品作為直接連接,但在其他工程,排隊的連接。
阻塞隊列連接 :咦!? 不只是三? 那麼,這是該文章閱讀的優勢之一:節省您的文件不一致! 這種連接是類似排隊的連接,只是該線程被阻塞,直到信號被正式執行的信號。 請注意,只能使用非常謹慎,在不同的線程信號和槽。 使用不當也可能導致死鎖。 你會知道當你看到這樣的事情:
用戶 @主機:〜/秒錶 $ /秒錶 QT:死鎖檢測而激活BlockingQueuedConnection:發件人 QPushButton(0x807e2d8)接收MyDisplay(0x8076ac0)
為解決有關問題是什麼意思“線程一個對象所在”指的是QT arespeito線程。
始終採取信號,槽,線程和定時器非常謹慎。 這是QT的主要特點,但其濫用可導致錯誤極難找到。 查看所有關於它的文檔。
到源
我們的例子是由兩個類和MyDisplay秒錶和一個共同文件的主。 主,只有創建一個 QApplication對象秒錶。 這個類負責 MyDisplay方案的視覺部分的護理,一個按鈕和一個液晶顯示樣式對話組成。 Stopwatch類別將創建一個小部件顯示和執行計時器。 請注意,這個架構是不是最elegent,更有趣的繼承類秒錶 MyDisplay。 但是,這會破壞的樂趣幾乎無需使用信號和槽。
對信號和槽的使用變得更清晰,當我們想要的對象與外界溝通。 一般來說,類不知道什麼是外。 在它們的指針傳遞到外部對象,它傷害了封裝,使通用的代碼較少。 在我們的例子,更有趣的使用信號和槽是myDisplay的對象(內部秒錶)報告事件從 /到對象秒錶(外部Mydisplay)它,沒有得到的一般性或封裝丟失。
隨著 Qt的設計(在另一篇文章中我將討論它)的幫助下,我創建了對話框,按鈕和LCD。 經過簡化的代碼,以滿足我們的目的。 如何myDisplay繼承 QDialog的,間接繼承自QObject,使用信號和槽只需添加在類的私有部分聲明 Q_OBJECT宏。 之後,我說等輔助方法:
公共插槽: long ) ; slotDisplayValue 無效(長); 私人插槽: slotPlay 無效 (); slotStop 無效 (); 信號: signalPlay 無效 (); signalPause 無效 (); signalStop 無效 (); signalReset 無效 ();
有跡象傳達給相關的按鈕點擊的外部事件。 已經是私有槽將前處理過程,而公眾有權從外部計時器刻度的。 因此,類向外界發送信息和接收來自外界的信息不知道什麼是在對方的。 好老接口的合同。
公共插槽: slotPlay 無效 (); slotPause 無效 (); slotStop 無效 (); slotReset 無效 (); 私人插槽: slotTick 無效 (); 信號: long ) ; signalTicks 無效(長);
模擬和相反的StopWatch類實現了插槽,接收信號 MyDisplay類,並聲明的信號發送信息向公眾槽。
它也實現了一個 QTime,將火災每10毫秒(讓我們的朋友可以按照lerdinhos Vista的!),遞增計數器。 此計數器是發回的顯示格式和顯示。
定時器可以停止,暫停和隨時重新啟動通過點擊相應的按鈕。
該 Finalmentes
這個例子本身並沒有多少代碼,但它說明了定時器和定制信號和槽建設最基本的使用。 一個很特別的關注,但是,應給予細節,涉及利用這些資源,就可以成為致命的陷阱。
重要鏈接
評論
- Walison
- Walison
- Blaber
- Blaber
- 羅德里戈
- 羅德里戈
- 盧卡斯
- 盧卡斯
- http://blabos.pip.verisignlabs.com/ 多嘴
- http://blabos.pip.verisignlabs.com/ 多嘴
- 盧卡斯
- 盧卡斯

