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.
Peasy facile! Le problème est que j'ai beaucoup de A chacun avec leur propre ensemble de signaux et de slots (les B/C sont plus génériques). Jusqu'à présent, j'ai fait manuellement une méthode de connexion et de déconnexion pour chaque type de classe différent. Les méthodes sont essentiellement des copies les unes des autres échangeant l'appel connect
contre disconnect
, allant à l'encontre de ne vous répétez pas ).
Ma question est donc 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?
}
J'ai fouillé dans la documentation QMetaObject , QObject et Signals and Slots sans succès (bien que ce ne soit souvent pas une garantie .. .).
Il y a au moins 2 façons. Tout d'abord, déconnectez tout.
disconnect(obj,0,0,0);
//or
obj->disconnect();
Seconde. Chaque connect()
renvoie QMetaObject::Connection
qui peut être copié ou déplacé, de sorte que vous pouvez enregistrer certaines 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 prend pas en charge une introspection aussi profonde, vous ne pouvez pas obtenir la liste de tous les emplacements connectés ou quelque chose d'autre, mais dans la plupart des cas, vous n'en avez pas du tout besoin. Une info utile, que Qt vous donne est sender()
, pointeur vers l'objet qui a envoyé le signal.
Modifier
Comme doc l'a dit:
Déconnectez tout ce qui est connecté aux signaux d'un objet
Ainsi, dans l'exemple suivant, les deux fenêtres seront affichées:
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 décommentez a->disconnect();
et seules les fenêtres A
seront affichées. Cela signifie que QObject::connect(b,SIGNAL(objectNameChanged(QString)),a,SLOT(show()));
n'était pas déconnecté comme indiqué dans la doc. Si vous voulez résoudre ce casse-tête, vous pouvez faire a->disconnect(b);b->disconnect(a);
, mais c'est bien sûr une 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");