2014-10-14 16 views
6

Posso usare un tipo di modello in qualsiasi modo come argomento slot o segnale? Per fare un esempio, sto cercando di definire quanto segue:Come utilizzare i tipi di modello come parametri di slot e segnale in più thread?

void exampleSignal(std::map<non_template_type_1,non_template_type_2> arg); 
void exampleSlot(std::map<non_template_type_1,non_template_type_2> arg); 

Il risultato è il seguente durante il runtime:

QObject::connect: Cannot queue arguments of type 
    'std::map<non_template_type_1,non_template_type_2>' 
(Make sure 'std::map<non_template_type_1,non_template_type_2>' 
    is registered using qRegisterMetaType().) 

Cercando di registrare std::map<non_template_type_1,non_template_type_2> con Q_DECLARE_METATYPE() risultati in fallimento la compilazione e apparentemente non è supportato .

Per ovviare al problema, sto utilizzando QVariantMap anziché std::map. Ma mi piacerebbe davvero conoscere il modo corretto per risolvere questo problema; uno in cui non è possibile modificare le classi template.

Modifica: Ho dimenticato di menzionare che il segnale e lo slot sono emessi e ricevuti in thread diversi. Apparentemente l'errore di runtime non si verifica in scenari a thread singolo.

risposta

2

Come spiegato in this thread si può provare con un typedef, compresa l'intestazione QMetaType e quindi utilizzando sia Q_DECLARE_METATYPE macro e la funzione qRegisterMetaType (come implica this thread su un problema simile).

+0

In realtà, ho confermato che funziona senza 'Q_DECLARE_METATYPE' quindi' qRegisterMetaType' sembra sufficiente insieme a 'typedef'. Non so quanto sia sicuro omettere 'Q_DECLARE_METATYPE'. –

2

questo funziona per me:

qRegisterMetaType< std::vector<float> >("std::vector<float>"); 
qRegisterMetaType< std::vector<int> >("std::vector<int>" ); 
qRegisterMetaType< std::map<std::string,int64_t> >("std::map<std::string,int64_t>"); 
1

non c'è nessun problema se è stata creata la classe come questa e utilizzato il moc compilatore Qt per creare quei QMetaObject s' automaticamente:

class MyClass : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit MyClass(QObject *parent = 0) 
     : QObject(parent) 
    { 
    } 
public slots: 
    void exampleSlot(std::map<non_template_type_1,non_template_type_2> arg); 
signals: 
    void exampleSignal(std::map<non_template_type_1,non_template_type_2> arg); 
}; 

Naturalmente è necessario includere QObject e ovunque std::map si trova a.

+0

Grazie, in effetti questo sembra possibile in un'impostazione a thread singolo, ma ho dimenticato di dire che non è il mio caso. –

+0

@ AyberkÖzgür Allora qual è il problema? Il segnale verrà sempre ricevuto in Qt Event Handler Thread – msrd0

+0

Non lo è. Vedi QueuedConnection in http://qt-project.org/doc/qt-4.8/threads-qobject.html#signals-and-slots-across-threads. –