2011-12-16 137 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