2011-12-16 15 views
7

Questa è una soluzione lunga ma, avendo riscontrato un vincolo in una forma di segnali di qt, le slot non possono essere templatizzate, sto solo pensando di sostituirle con segnali di boost, sarebbe quello essere un'opzione praticabile?utilizzando segnali di boost invece di qt

+2

Come lo sappiamo? In generale sì, non c'è assolutamente nulla di sbagliato in Boost.Signals, ma spetta a te decidere se Boost è giusto per il tuo particolare problema. –

risposta

10

Non sei obbligato a utilizzare i segnali e gli slot di qt. Da Using Qt with 3rd Party Signals and Slots:

È possibile utilizzare Qt con un meccanismo di segnale/slot di terze parti. È possibile utilizzare entrambi meccanismi nello stesso progetto. Basta aggiungere la riga al file qmake project (.pro).

CONFIG += no_keywords 

dice Qt di non definire la moc segnali parole chiave, gli slot, ed emettono, perché questi nomi saranno utilizzati da una libreria di terze parti, ad esempio, Incremento. Quindi per continuare a utilizzare i segnali Qt e gli slot con il flag no_keywords, è sufficiente sostituire tutti gli usi delle parole chiave Qt Moc nelle sorgenti con le macro Qt corrispondenti Q_SIGNALS (o Q_SIGNAL), Q_SLOTS (o Q_SLOT) e Q_EMIT.

C'è un complete explanation di come collegare i segnali di boost ai segnali qt.


Ho trovato questo adattatore da qualche parte sulla rete, ma nessuna idea di dove:

#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 

Quindi, in pratica si devono reimplementare qt_metacall funzione.

+2

Qt 5 supporta i segnali di connessione a funzioni arbitrarie fuori dalla scatola - vedi http://qt-project.org/wiki/New_Signal_Slot_Syntax Per Qt 4, ci sono alcune librerie di adattatori. Il mio tentativo di questo più collegamenti ad altri può essere trovato a https://github.com/robertknight/qt-signal-tools –

+0

@RobertKnight Dovrebbe essere una risposta (una buona, se me lo chiedi). Finalmente hanno preso una buona decisione per quanto riguarda il loro segnale/slot –

+1

Decisione molto buona, davvero. Finalmente sbarazzati del moc (* king *)! –