久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

深入理解信號(hào)槽(四)

 just_person 2013-04-25

將 Qt 的信號(hào)槽系統(tǒng)與 Boost.Signals 結(jié)合使用

實(shí)際上,,將 Qt 的信號(hào)槽系統(tǒng)與 Boost.Signals 結(jié)合在一起使用并非不可能,。通過前面的闡述,,我們都知道了二者的不同,,至于為什么要將這二者結(jié)合使用,,則是見仁見智的了,。這里,,我們給出一種結(jié)合使用的解決方案,,但是并不是說我們暗示應(yīng)該將它們結(jié)合使用,。這應(yīng)該是具體問題具體分析的。

將 Qt 的信號(hào)槽系統(tǒng)與 Boost.Signals 結(jié)合使用,,最大的障礙是,,Qt 使用預(yù)處理器定義了關(guān)鍵字 signals,slots 以及 emit,。這些可以看做是 Qt 對(duì) C++ 語(yǔ)言的擴(kuò)展,。同時(shí),Qt 也提供了另外一種方式,,即使用宏來(lái)實(shí)現(xiàn)這些關(guān)鍵字,。為了屏蔽掉這些擴(kuò)展的關(guān)鍵字,Qt 4.1 的 pro 文件引入了 no_keywords 選項(xiàng),,以便使用標(biāo)準(zhǔn) C++ 的方式,,方便 Qt 與其他 C++ 同時(shí)使用。你可以通過打開 no_keywords 選項(xiàng),,來(lái)屏蔽掉這些關(guān)鍵字,。下面是一個(gè)簡(jiǎn)單的實(shí)現(xiàn):

# TestSignals.pro (platform independent project file, input to qmake)
#   showing how to mix Qt Signals and Slots with Boost.Signals
  #
  # Things you'll have in your .pro when you try this...
  #
CONFIG += no_keywords
  # so Qt won't #define any non-all-caps `keywords'
INCLUDEPATH += . /usr/local/include/boost-1_33_1/
  # so we can #include <boost/someheader.hpp>
macx:LIBS   += /usr/local/lib/libboost_signals-1_33_1.a
  # ...and we need to link with the Boost.Signals library.
  # This is where it lives on my Mac,
  #   other platforms would have to add a line here
  #
  # Things specific to my demo
  #
CONFIG -= app_bundle
  # so I'll build a command-line tool instead of a Mac OS X app bundle
HEADERS += Sender.h Receiver.h
SOURCES += Receiver.cpp main.cpp

請(qǐng)注意,我們已經(jīng)在 pro 文件中打開了 no_keywords 選項(xiàng),,那么,,類似 signals 這樣的關(guān)鍵字已經(jīng)不起作用了。所以,,我們必須將這些關(guān)鍵字修改成相應(yīng)的宏的版本,。例如,我們需要將 signals 改為 Q_SIGNALS,,將 slots 改為 Q_SLOTS 等等,。請(qǐng)看下面的代碼:

// Sender.h
#include <QObject>
#include <string>
#include <boost/signal.hpp>
class Sender : public QObject
{
    Q_OBJECT
Q_SIGNALS:  // a Qt signal
    void qtSignal( const std::string& );
    // connect with
    //  QObject::connect(sender, SIGNAL(qtSignal(const std::string&)), ...
public:     // a Boost signal for the same signature
    boost::signal< void ( const std::string& ) >  boostSignal;
    // connect with
    //  sender->boostSignal.connect(...
public:     // an interface to make Sender emit its signals
    void sendBoostSignal( const std::string& message ) {
        boostSignal(message);
    }

    void sendQtSignal( const std::string& message ) {
        qtSignal(message);
    }
};

現(xiàn)在我們有了一個(gè)發(fā)送者,下面來(lái)看看接收者:

// Receiver.h
#include <QObject>
#include <string>

class Receiver : public QObject
{
    Q_OBJECT
public Q_SLOTS:
    void qtSlot( const std::string& message );
    // a Qt slot is a specially marked member function
    // a Boost slot is any callable signature
};

// Receiver.cpp
#include "Receiver.h"
#include <iostream>

void Receiver::qtSlot( const std::string& message )
{
    std::cout << message << std::endl;
}

下面,,我們來(lái)測(cè)試一下:

// main.cpp
#include <boost/bind.hpp>
#include "Sender.h"
#include "Receiver.h"

int main( int /*argc*/, char* /*argv*/[] )
{
    Sender* sender = new Sender;
    Receiver* receiver = new Receiver;

    // connect the boost style signal
    sender->boostSignal.connect(boost::bind(&Receiver::qtSlot, receiver, _1));
    // connect the qt style signal
    QObject::connect(sender, SIGNAL(qtSignal(const std::string&)),
                     receiver, SLOT(qtSlot(const std::string&)));
    sender->sendBoostSignal("Boost says 'Hello, World!'");
    sender->sendQtSignal("Qt says 'Hello, World!'");
    return 0;
}

這段代碼將會(huì)有類似下面的輸出:

[506]TestSignals$ ./TestSignals
Boost says 'Hello, World!'
Qt says 'Hello, World!'

我們可以看到,,這兩種實(shí)現(xiàn)的不同之處在于,,Boost.Signals 的信號(hào),,boostSignal,是 public 的,,任何對(duì)象都可以直接發(fā)出這個(gè)信號(hào),。也就是說,我們可以使用如下的代碼:

sender->boostSignal("Boost says 'Hello, World!', directly");

從而繞過我們?cè)O(shè)置的 sendBoostSignal() 這個(gè)觸發(fā)函數(shù),。另外,,我們可以看到,,boostSignal 完全可以是一個(gè)全局對(duì)象,這樣,,任何對(duì)象都可以使用這個(gè)信號(hào),。而對(duì)于 Qt 來(lái)說,signal 必須是一個(gè)成員變量,,在這里,,只有 Sender 可以使用我們定義的信號(hào)。

這個(gè)例子雖然簡(jiǎn)單,,然而已經(jīng)很清楚地為我們展示了,,如何通過 Qt 發(fā)出信號(hào)來(lái)獲取 Boost 的行為。在這里,,我們使用一個(gè)公共的 sendQtSignal() 函數(shù)發(fā)出 Qt 的信號(hào),。然而, 為了從 Boost 的信號(hào)獲取 Qt 的行為,,我們需要多做一些工作:隱藏信號(hào),,但是需要提供獲取連接的函數(shù)。這樣看上去有些麻煩:

class Sender : public QObject
{
    // just the changes...
private:
    // our new public connect function will be much easier to understand
    //  if we simplify some of the types
    typedef boost::signal< void ( const std::string& ) > signal_type;
    typedef signal_type::slot_type                       slot_type;
    signal_type  boostSignal;
    // our signal object is now hidden
public:
    boost::signals::connection
    connectBoostSignal( const slot_type& slot,
                        boost::signals::connect_position pos = boost::signals::at_back ) {
        return boostSignal.connect(slot, pos);
    }
};

應(yīng)該說,,這樣的實(shí)現(xiàn)相當(dāng)丑陋,。實(shí)際上,我們將 Boost 的信號(hào)與連接分割開了,。我們希望能夠有如下的實(shí)現(xiàn):

// WARNING: no such thing as a connect_proxy
class Sender
{
public:
    connect_proxy< boost::signal< void ( const std::string& ) > >
    someSignal() {
        return someSignal_;
        // ...automatically wrapped in the proxy
    }
private:
    boost::signal< void ( const std::string& ) > someSignal_;
};
sender->someSignal().connect(someSlot);

注意,,這只是我的希望,并沒有做出實(shí)現(xiàn),。如果你有興趣,,不妨嘗試一下。

總結(jié)

前面啰嗦了這么多,,現(xiàn)在總結(jié)一下,。

信號(hào)和槽的機(jī)制實(shí)際上是觀察者模式的一種變形。它是面向組件編程的一種很強(qiáng)大的工具?,F(xiàn)在,,信號(hào)槽機(jī)制已經(jīng)成為計(jì)算機(jī)科學(xué)的一種術(shù)語(yǔ),也有很多種不同的實(shí)現(xiàn),。

Qt 信號(hào)槽是 Qt 整個(gè)架構(gòu)的基礎(chǔ)之一,,因此它同 Qt 提供的組件、線程,、反射機(jī)制,、腳本、元對(duì)象機(jī)制以及可視化 IDE 等等緊密地集成在一起。Qt 的信號(hào)是對(duì)象的成員函數(shù),,所以,,只有擁有信號(hào)的對(duì)象才能發(fā)出信號(hào)。Qt 的組件和連接可以由非代碼形式的資源文件給出,,并且能夠在運(yùn)行時(shí)動(dòng)態(tài)建立這種連接,。Qt 的信號(hào)槽實(shí)現(xiàn)建立在 Qt 元對(duì)象機(jī)制之上。Qt 元對(duì)象機(jī)制由 Qt 提供的 moc 工具實(shí)現(xiàn),。moc 也就是元對(duì)象編譯器,,它能夠?qū)⒂脩糁付ǖ木哂?Q_OBJECT 宏的類進(jìn)行一定程度的預(yù)處理,給這個(gè)增加元對(duì)象能力,。

Boost.Signals 是具有靜態(tài)的類型安全檢查的,,基于模板的信號(hào)槽系統(tǒng)的實(shí)現(xiàn)。所有的信號(hào)都是模板類 boost::signal 的一個(gè)特化,;所有的槽函數(shù)都具有相匹配的可調(diào)用的簽名,。Boost.Signals 是獨(dú)立的,不需要內(nèi)省,、元對(duì)象系統(tǒng),,或者其他外部工具的支持。然而,,Boost.Signals 沒有從資源文件動(dòng)態(tài)建立連接的能力,。

這兩種實(shí)現(xiàn)都非常漂亮,并且都具有工業(yè)強(qiáng)度,。將它們結(jié)合在一起使用也不是不可能的,,Qt 4.1 即提供了這種可能性。

任何基于 Qt GUI 的系統(tǒng)都會(huì)自然而然的使用信號(hào)槽,。你可以從中獲取很大的好處,。任何大型的系統(tǒng),如果希望能夠降低組件之間的耦合程度,,都應(yīng)該借鑒這種思想,。正如其他的機(jī)制和技術(shù)一樣,最重要的是把握一個(gè)度,。在正確的地方使用信號(hào)槽,,可以讓你的系統(tǒng)更易于理解、更靈活,、高度可重用,,并且你的工作也會(huì)完成得更快。

本文出自 “豆子空間” 博客,,請(qǐng)務(wù)必保留此出處http://devbean.blog.51cto.com/448512/428364

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多