2014-11-06 79 views
0

我正在經歷一個Qt教程here,當我遇到這個下面的代碼段傳來:Qt類中的插槽和信號是什麼意思?

#include <QObject> 

class Counter : public QObject 
{ 
    Q_OBJECT 

public: 
    Counter() { m_value = 0; } 

    int value() const { return m_value; } 

public slots: 
    void setValue(int value); 

signals: 
    void valueChanged(int newValue); 

private: 
    int m_value; 
}; 

任何人都可以向我解釋什麼是public slotssignals在聲明中的使用情況如何?我雖然只有兩個,publicprivate。他們叫什麼,他們的用法是什麼?

+1

@Cupidvogel:呵呵,我錯過了一個鏈接。所以,你最好再次閱讀該文檔......這是你應該清楚理解的Qt基礎知識。官方文件對此很清楚。 – zaufi 2014-11-06 22:41:27

+0

看起來像。巴里,你最好關閉這個問題嗎? – SexyBeast 2014-11-06 22:41:45

+0

它需要3個更接近的選票。 – JBL 2014-11-06 22:42:33

回答

3

信號和槽是Qt中引入對象之間 通信的語言結構[1]這使得它易於實現 觀察者模式,同時避免樣板代碼。其概念是, GUI小部件可以使用稱爲插槽的特殊功能發送包含由其他控件接收的事件信息的信號,該事件信息可以是 。

信號/槽系統與方法的圖形用戶 接口被設計合身。類似地,信號/槽系統可以用於 其它非GUI用途,例如異步I/O(包括 套接字,管道,串行設備等)的事件通知,或與適當的對象實例和 關聯超時事件方法 或功能。它易於使用,不需要 註冊/註銷/調用代碼寫入, 因爲Qt的元對象編譯器(MOC)自動生成 必要的基礎設施。

通常使用的隱喻是一個電子表格。電子表格具有觀察源單元格的單元格 。當源單元格更改時,將從事件更新依賴單元格 。

不差Wikipedia


解釋由於Qt的基本發明了你真正看到你在你的問題發表的文章這將是最好的概念。

特別:

信號

信號由物體發出時,其內部狀態在某種程度上可能是有趣的對象的客戶或者老闆發生了變化 。 只有定義信號及其子類的類纔可以發出信號 。

當一個信號被髮射時,與它相連的槽通常是 立即執行,就像一個正常的函數調用。當發生這種情況時,信號和插槽機制完全獨立於任何GUI事件循環。一旦所有插槽已經返回,將在發出語句 之後執行代碼。當使用排隊連接時,情況略有不同; 不同;在這種情況下,emit關鍵字後面的代碼 將立即繼續,並且將在稍後執行插槽 。

如果多個插槽連接到一個信號,則插槽將依次執行,依次爲 ,按照它們已連接的順序執行, 發出信號時。

信號由moc自動生成,並且不得在.cpp文件中實現 。它們不能有返回類型(即 使用void)。

關於參數的說明:我們的經驗表明,如果信號和插槽 不使用特殊類型,則它們更具可重用性。如果 QScrollBar :: valueChanged()將使用特殊類型,例如 假設的QScrollBar :: Range,則它只能連接到專門爲QScrollBar設計的插槽 。將不同的輸入 小部件連接在一起將是不可能的。

槽孔

在連接到它的信號被髮射的時隙被調用。插槽是 正常的C++函數,可以正常調用;他們唯一特別的 功能是信號可以連接到它們。

由於插槽是正常的成員函數,因此它們在直接調用時遵循正常的C++ 規則。但是,作爲插槽,可以通過 連接,通過 任意組件調用它們,而不管其訪問級別如何。這意味着從任意類的實例發出的信號可以導致在不相關類的實例 中調用專用插槽。

您也可以將插槽定義爲虛擬的,我們已經發現在實踐中很有用 。

與回調相比,信號和時隙稍慢,因爲它們提供的靈活性增加了 ,但實際應用的差異並不顯着。一般來說,發出一個信號 連接到某些插槽,大約比 直接調用接收器慢十倍,並且帶有非虛函數調用。此 是定位連接對象所需的開銷,以安全地對所有連接進行迭代(即,檢查後續接收器 在發射期間未被破壞),並且以通用方式編組任何 參數。雖然十個非虛函數調用 可能聽起來很多,但它比任何新操作或刪除操作都要少得多。只要您執行字符串,矢量或列表操作,幕後操作需要新增或刪除,則信號和插槽開銷只負責完成函數調用成本的非常小的比例。

只要你在一個插槽中進行系統調用,情況也是如此;或者間接調用十個以上的函數。在i586-500上,你可以發出大約每秒鐘連接到一個接收器的2,000,000個信號的 ,或者連接到兩個接收器的每秒大約1,200,000個發射器 。 的簡單性和信號和插槽機制的靈活性非常值得 開銷,您的用戶甚至不會注意到。

請注意,與基於Qt的應用程序一起編譯時,定義名爲signals或 插槽的變量的其他庫可能會導致編譯器警告和錯誤。爲了解決這個問題,#undef有問題的 預處理符號。