2011-12-16 9 views
7

これは長いショットですが、qtのシグナルの形で制約を迎えているため、スロットをテンプレート化できないため、ブースト信号で置き換えることを考えています。実行可能な選択肢ですか?qtの代わりにブースト信号を使用

+2

私たちはどのように知っていますか?一般的にはい、Boost.Signalsには何も問題はありませんが、Boostがあなたの特定の問題に適しているかどうかはあなた自身が決定します。 –

答えて

10

qtの信号とスロットは強制的に使用されません。 Using Qt with 3rd Party Signals and Slots

サードパーティのシグナル/スロットメカニズムでQtを使用することは可能です。 では、同じプロジェクトで両方のメカニズムを使用することもできます。 qmakeプロジェクト(.pro)ファイルに、次の行を に追加してください。

CONFIG += no_keywords 

それは、これらの名前は、例えば、サードパーティのライブラリで使用されるため、MOCのキーワード信号、スロット、および放射する、 を定義していないのQtを伝えますブースト。 その後、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で見つけることができます。 –

+0

@RobertKnight回答があったはずです。最終的に彼らは彼らの信号/スロットに関して良い決定を下した –

+1

確かに、非常に良い決定。最後にmoc(* king *)を捨てなさい! –