2015-08-20 1 views
15

J'ai un QObject A, celui-ci est connecté à un autre QObject B. Maintenant, je veux que A se connecte à C, un troisième QObject et se déconnecte complètement de B.Est-il possible de déconnecter toutes les connexions d'un QObject sans le supprimer

Facile peasy! Le problème est que j'ai beaucoup de A avec leur propre ensemble de signaux et de slots (les B/C sont plus génériques). Jusqu'à présent, j'ai créé manuellement une méthode de connexion et de déconnexion pour chaque type de classe. Les méthodes sont essentiellement des copies les unes des autres échangeant l'appel connect pour disconnect, en allant contre le don't repeat yourself). Donc, ma question est la suivante: la fonction suivante est-elle possible?

void deleteAllConnections(QObject* someObject) { 
    // TODO disconnect all connections owned by someObject 
    // For bonus points: Is there a way of accessing the QMetaObject connected to? 
} 

Je l'ai poussé autour du QMetaObject, QObject et la documentation Signals and Slots sans chance (bien que ce soit souvent pas une garantie ...).

+0

'QObject :: disconnect();' http://doc.qt.io/qt-5/qobject.html#disconnect-5 – drescherjm

+0

@drescherjm que états de la documentation 'Déconnecte tous les signaux de cet objet de la méthode du récepteur. 'Je lis cela car il déconnecte tous les signaux de ** cet ** objet des fentes ** de l'autre ** objet, mais je ne suis toujours pas sûr si c'est aussi déconnecte les signaux d'autres ** objets ** des emplacements de ** cet ** objet. – Troyseph

Répondre

33

Il existe au moins 2 façons. Tout d'abord, déconnectez tout.

disconnect(obj,0,0,0); 
//or 
obj->disconnect(); 

Deuxième. Chaque connect() renvoie QMetaObject::Connection qui peut être copié ou déplacé, de sorte que vous pouvez enregistrer des connexions dans la liste et après un certain temps, il suffit de parcourir la liste et d'appeler disconnect() pour chaque objet. Exemple avec une connexion:

QMetaObject::Connection m_connection; 
//… 
m_connection = QObject::connect(…); 
//… 
QObject::disconnect(m_connection); 

Bonus: non, Qt ne supporte pas une telle introspection profonde, vous ne pouvez pas obtenir la liste de tous les emplacements connectés ou quelque chose une autre, mais dans la plupart des cas, vous n'avez pas besoin de cette du tout. Une information utile, que Qt vous donne est sender(), pointeur vers l'objet qui a envoyé le signal.

Modifier

Comme doc dit:

tout Déconnecter connecté aux signaux d'un objet

Ainsi, dans l'exemple suivant les deux fenêtres se:

QWidget *a = new QWidget; 
QWidget *b = new QWidget; 

a->setWindowTitle("A"); 
b->setWindowTitle("B"); 

QObject::connect(a,SIGNAL(objectNameChanged(QString)),b,SLOT(show())); 
QObject::connect(b,SIGNAL(objectNameChanged(QString)),a,SLOT(show())); 

//a->disconnect(); 

a->setObjectName("A"); 
b->setObjectName("B"); 

Mais ne pas commenter a->disconnect(); et seules les fenêtres A seront affichées. Cela signifie que QObject::connect(b,SIGNAL(objectNameChanged(QString)),a,SLOT(show())); n'a pas été déconnecté comme indiqué dans le doc. Si vous voulez résoudre ce puzzle, vous pouvez faire a->disconnect(b);b->disconnect(a);, mais il est bien sûr très mauvaise approche. Vous pouvez donc utiliser la deuxième suggestion de ma réponse:

QList<QMetaObject::Connection> connections; 

QWidget *a = new QWidget; 
QWidget *b = new QWidget; 

a->setWindowTitle("A"); 
b->setWindowTitle("B"); 

connections << QObject::connect(a,SIGNAL(objectNameChanged(QString)),b,SLOT(show())); 
connections << QObject::connect(b,SIGNAL(objectNameChanged(QString)),a,SLOT(show())); 

foreach (auto var, connections) { 
    QObject::disconnect(var); 
} 

a->setObjectName("A"); 
b->setObjectName("B"); 
+0

Bonne réponse, est-ce que 'tout déconnecter 'déconnecte les connexions entrantes et sortantes? – Troyseph

+1

@SebastianTroy Voir les réponses aux questions – Chernobyl