2016-09-14 2 views
2

Je tente d'envoyer une structure via des signaux/slots entre deux threads, mes signaux/slots sont connectés correctement et j'ai pu envoyer QStrings contenant des parties de mes données, mais maintenant j'ai besoin pour envoyer le tout et Structures semblent les plus sensibles. Cependant quand j'essaye le signal n'est pas envoyé/reçu. Le problème semble être seulement avec l'envoi/réception de la structure, le traitement avant et après j'ai essayé de nombreuses façons.Qt Signal/Slots envoyer une structure complète

Je ne peux pas utiliser des pointeurs tels que here ou here car mes données sont générées trop rapidement et la mémoire est écrasée ou libérée (j'ai essayé avec des pointeurs et suppose que les références seront effectuées de la même manière). J'ai déjà ajouté Q_DECLARE_METATYPE à ma structure. Ma structure n'est qu'un petit test pour l'instant (pour être agrandi plus tard) et se trouve dans son propre fichier d'en-tête. Pourquoi mon programme ne pourrait-il pas envoyer/recevoir des structures?

#ifndef RETURNSTRUCT_H 
#define RETURNSTRUCT_H 

struct Datastruct 
{ 
    int markeridone; 
}; 

Q_DECLARE_METATYPE(Datastruct); 

#endif //RETURNSTRUCT_H 

Toute aide est très appréciée.

J'utilise windows 7, MinGW 32bit, Qt 5.7.0, Qt Creator 4.0.3

Répondre

7

Votre debug-journal doit vous avertir à ce sujet - vous ne pouvez envoyer les types connus de la méta-système de qt . En utilisant Q_REGISTER_METATYPE vous finissez par enregistrer les types associés à l'espace de noms où la définition a été faite.

vous pouvez dire Heureusement Qt votre struct comme ceci:

// after QApplication was instantiated 
qRegisterMetaType<Datastruct>("Datastruct"); 
// but before any class is instantiated that connects signals with this type 

Et il ne sera pas essayer de déduire un espace de nom en regardant le code. Assurez-vous de relancer qmake (ou mieux encore de faire un nettoyage), ou il pourrait être négligé lors de la construction avec QtCreator.

Si vous arrive plus tard pour passer des classes abstraites de vos types au moyen de signaux, assurez-vous de les enregistrer aussi bien, parce que même si Qt sait QList, il ne marche pas au courant de QList de votre type:

qRegisterMetaType<QList<Datastruct>>("QList<Datastruct>"); 

Sur une autre note: si vous # définissez des alias de classes, assurez-vous de les enregistrer avec leur vrai nom.

#define std::shared_ptr model_ptr 
// you can declare your signals like this: 
void my_signal(model_ptr<my_model>); 
// but have to register the type like this: 
qRegisterMetaType<std::shared_ptr<my_model>>("std::shared_ptr<my_model>"); 
+1

Pourquoi oh pourquoi proposeriez-vous jamais utiliser '# define' ici? Même en C c'était inutile (vous aviez typedef)! En C++, vous êtes supposé utiliser des alias de type: 'using model_ptr = std :: shared_ptr '. Il est également tout à fait correct d'utiliser l'alias uniquement, pas le nom de type sous-jacent, tant que vous l'utilisez systématiquement partout. –

+0

Je donnais un exemple qui ressemblait à un cas que j'avais, qui était un mal de tête à épingler, ** au cas où vous utilisez déjà # define ** - pas _suggesting_ pour utiliser #define –

+0

Enregistrement d'un * La classe template * peut ne pas fonctionner telle quelle, vous devrez peut-être d'abord utiliser 'typedef' ou' using ', puis enregistrer l'alias. Notez également que les doubles accolades angulaires à la fin d'un type de modèle ne sont autorisées que ** C++ 11 et plus **. N'en faites pas votre habitude si vous travaillez pour d'autres projets! – iksemyonov

1

En moment, lorsque vous déclarez structure connue à l'aide QMetaType macro Q_DECLARE_METATYPE

struct Datastruct 
{ 
    int markeridone; 
}; 

Q_DECLARE_METATYPE(Datastruct) 

vous pouvez envoyer cette structure par QVariant. Est gentil et simple. dans vos têtes déclare:

signals: 
    void sendDatastruct(QVariant data); 

public slots: 
    void getDatastruct(QVariant data); 

utilisant le signal dans votre code:

..... 
Datastruct ds; 
..... 
QVariant data; 
data.setValue(ds); 
emit sendDatastruct(data); // now send signal 
..... 

emplacement avec:

void MyObject::getDatastruct(QVariant data) 
{ 
    Datastruct ds = data.value<Datastruct>(); 
    ..... 
    // now You can use structure in Your code 
}