2010-02-24 111 views
22

我們使用Qt提供的信號和插槽,我發現真的是方便。然而,強大的力量帶來了巨大的責任,我認爲這種功能很容易被濫用。什麼時候使用信號和插槽,什麼時候不使用

是否有信號插槽使用的最佳做法?我很難用這種方式找到一些通用的指導方針。一些問題(我有明確的意見,但不是我的團隊所有成員都同意):

  • 可以使用信號來報告錯誤嗎?
  • 可以假設信號會被處理嗎?
  • 可以使用信號來啓動操作嗎?例如。 signal displayInfoScreen()必須由顯示信息屏幕的插槽來處理。

關於什麼時候應該/不應該使用信號的任何其他意見是很歡迎歡迎!

回答

12

它是確定使用信號來報告
錯誤?

是的,例如,參見QFtp,其中完成的信號攜帶狀態。它不包含實際的錯誤,只是發生錯誤的信息。

可以假設信號 被處理?

不是。發件人永遠不會認爲您的特定應用程序可以依賴它。例如,代表File - New的QAction需要被處理才能使應用程序正常工作,但QAction對象並不在乎。

可以使用信號來啓動 動作嗎?例如。信號 displayInfoScreen()必須由 處理一個顯示信息屏幕的插槽。

同樣,是的,例如QAction對象。但是如果你想能夠重用組件,你必須小心確保實際的類不依賴於它。

+0

接受此答案提供了在Qt中使用的簡單示例。你認爲錯誤是好的,但只有當處理是異步的時候? – larsmoa 2010-02-26 21:57:15

+0

謝謝!而且,是的,否則,請添加狀態返回值或狀態參數(如QString :: toInt所做的那樣)。 – e8johan 2010-02-28 09:28:56

10

可以假設信號會被處理嗎?

不,它不是。信號是火災和忘記類型的東西。誰連接到一個信號,它的作用不應該是發射器的問題。

3

信號/插槽(也稱爲事件)是消除對象之間耦合的好方法。

例如,不是具有理解模型如何工作的視圖,而是模型更改時,他們「傾聽」模型。該模型負責說明它何時發生變化,發生了什麼變化。

事件的問題是當您根據客戶需求設計事件時。例如,你不應該有一個信號displayInfoScreen,因爲它假設了一些關於使用這個信號的對象。相反,它應該是infoChangedInfoScreenDisplayer監聽此信號以在屏幕上顯示它。如果你需要,你可以稍後添加一個InfoTweeterPoster,只要他們改變就發佈Tweeter上的信息。

+6

你寫了a.k.a.事件,但事實並非如此。 Qt帶有一個單獨的事件基礎結構。 – e8johan 2010-02-24 16:38:50

11

信號和插槽功能強大,因爲decouples對象。正如以前所回答的那樣,您不能假定信號有插槽連接。

基於信號/槽設計的主要缺點是,你可以很容易了,履帶你實現,由於對象的一個​​動作可以觸發連接到發射的信號的任何其它物體的其他動作的邏輯。具有不需要的副作用,遞歸調用等容易得多。

5

可以使用信號來報告錯誤嗎?

是的,但我通常會做出這種情況依賴。如果錯誤可能異步發生,那麼表明這種情況的信號是絕對正確的。如果錯誤只發生在客戶代碼調用某個函數時,那麼錯誤應該來自該函數的響應,而不是信號。但是,在各個案例之間可能會有各種各樣的情況。另外,信號插槽機制可以使跨線程通信更容易(這可能被認爲是異步情況),並且我將使用它們用於該目的(錯誤或不)。

可以假設信號會被處理嗎?

信號(哲學上)被設計爲表示發生了某些事情。正如其他人所指出的那樣,假設一個信號將與一個插槽相匹配,或者甚至只與一個其他插槽相匹配也不是一個好主意。

可以使用信號來啓動操作嗎?例如。信號displayInfoScreen()必須由顯示信息屏幕的插槽處理。

信號可以用來啓動動作,但可能不像你想的那樣。該信號表明foo已經發生。如果監控班級的代碼決定發生10富時時應顯示一個對話框,然後使用該信號啓動該操作。然而,一般來說,發佈信號的職責不是確保發生適當的行爲,因爲它不負責執行該行爲。 (如果是的話,那應該是同一類的一部分,將需要無信號)。

相關問題