2011-12-16 64 views
7

這是一個長鏡頭,但是,遇到了qt的信號形式的限制,插槽無法模板化,我只是想用升壓信號替換它們,是可行的選擇?使用升壓信號,而不是qt

+2

我們怎麼知道?一般來說,Boost.Signals絕對沒有問題,但是由您決定Boost是否適合您的特定問題。 – 2011-12-16 12:09:03

回答

10

你不是被迫使用qt的信號和插槽。從Using Qt with 3rd Party Signals and Slots

可以將Qt與第三方信號/插槽機制一起使用。你甚至可以在同一個項目中使用兩種機制。只需將 以下行添加到您的qmake項目(.pro)文件中即可。

CONFIG += no_keywords 

它告訴Qt的不以限定的moc關鍵字信號,狹槽,併發射, 因爲這些名稱將由第三方庫被使用,例如促進。 然後繼續使用帶有no_keywords標誌的Qt信號和槽, 只需將源中的Qt moc關鍵字的所有用法與相應的Qt宏Q_SIGNALS(或Q_SIGNAL),Q_SLOTS(或 Q_SLOT)和Q_EMIT替換爲 即可。

有關於如何將升壓信號連接到qt信號的complete explanation


我發現某處在網上這個適配器,但不知道從哪裏:

#ifndef _QT_2_FUNC_3_H_ 
#define _QT_2_FUNC_3_H_ 

#include <iostream> 

#include <boost/function.hpp> 
#include <boost/type_traits.hpp> 

#include <QObject> 

#include <libQtSignalAdapters/QtConnDefault.h> 

using namespace boost; 

namespace QtSignalAdapters 
{ 

/** 
* \cond 
*/ 
template<typename SIGNATURE> 
class Qt2FuncSlot3 
{ 
public: 
    typedef function<SIGNATURE> FuncType; 
    typedef typename function_traits<SIGNATURE>::arg1_type ParmType1; 
    typedef typename function_traits<SIGNATURE>::arg2_type ParmType2; 
    typedef typename function_traits<SIGNATURE>::arg3_type ParmType3; 

    Qt2FuncSlot3(const FuncType& func) : 
     func_(func) 
    { 
    } 

    void call(QObject* sender, void **arguments) 
    { 
     ParmType1* a1 = reinterpret_cast<ParmType1*>(arguments[1]); 
     ParmType2* a2 = reinterpret_cast<ParmType2*>(arguments[2]); 
     ParmType3* a3 = reinterpret_cast<ParmType3*>(arguments[3]); 
     if (func_) 
      func_(*a1,*a2, *a3); 
    } 

private: 
    FuncType func_; 
}; 
/** 
* \endcond 
*/ 

template<typename SIGNATURE> 
class Qt2Func3 : public QObject, public QtConnDefault 
{ 
public: 
    typedef function<SIGNATURE> FuncType; 
    typedef typename function_traits<SIGNATURE>::arg1_type ParmType; 

    Qt2Func3(QObject* qobject, int signalIdx, const FuncType& func, 
      bool initiallyConnected=true) : 
     QObject(qobject), 
     QtConnDefault(qobject, signalIdx), 
     func_(func) 
    { 
     // 
     // Get the next usable slot ID on this... 
     // 
     slotIdx_ = metaObject()->methodCount(); 

     // 
     // Create a slot to handle invoking the boost::function object. 
     // 
     slot_ = new Qt2FuncSlot3<SIGNATURE>(func); 

     if (initiallyConnected) 
      connect(); 
    } 

    ~Qt2Func3() 
    { 
     delete slot_; 
    } 

    int qt_metacall(QMetaObject::Call c, int id, void **arguments) 
    { 
     id = QObject::qt_metacall(c, id, arguments); 
     if (id < 0 || c != QMetaObject::InvokeMetaMethod) 
      return id; 

     slot_->call(sender(), arguments); 
     return -1; 
    } 

    void connect() 
    { 
     connect_(); 
    } 

    void disconnect() 
    { 
     disconnect_(); 
    } 

private: 
    void connect_() 
    { 
     connected_ = 
      QMetaObject::connect(qobject_, signalIdx_, this, slotIdx_); 
    } 

    void disconnect_() 
    { 
     connected_ = 
      !QMetaObject::disconnect(qobject_, signalIdx_, this, slotIdx_); 
    } 


    FuncType func_; 
    Qt2FuncSlot3<SIGNATURE>* slot_; 
}; 

} 

#endif 

所以,基本上,你必須重新實現qt_metacall功能。

+2

Qt 5支持將信號連接到開箱即用的任意功能 - 請參閱http://qt-project.org/wiki/New_Signal_Slot_Syntax對於Qt 4,有幾個適配器庫。我試圖在這個加上其他鏈接可以在https://github.com/robertknight/qt-signal-tools找到 – 2013-01-29 17:34:49