2015-08-20 15 views
15

Ho un QObject A, questo è collegato a un altro QObject B. Ora voglio A connettersi a C, un terzo QObject e completamente disconnettere da B.È possibile disconnettere tutte le connessioni di QObject senza eliminarlo

Facile per niente! Il problema è che ho un sacco di A's ciascuno con il proprio set di segnali e slot (quelli di B/C sono più generici). Finora ho creato manualmente un metodo di connessione e disconnessione per ogni tipo di classe. I metodi sono sostanzialmente copie l'una dell'altra scambiando la connect per la chiamata disconnect, andando contro lo don't repeat yourself).

Quindi la mia domanda è: è possibile la seguente funzione?

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

ho curiosato nel QMetaObject, QObject e la documentazione Signals and Slots senza fortuna (anche se questo non è spesso una garanzia ...).

+0

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

+0

@drescherjm che stati della documentazione 'Disconnette tutti i segnali in questo oggetto dal metodo del ricevitore. Lo sto leggendo quando disconnette tutti i ** segnali ** di questo oggetto da ** altri ** slot degli oggetti, ma non sono ancora sicuro se anche questo disconnette ** altri ** segnali di oggetti da ** questo ** slot dell'oggetto. – Troyseph

risposta

33

Ci sono almeno 2 modi. Innanzitutto, disconnetti tutto.

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

Secondo. Ogni connect() restituisce QMetaObject::Connection che può essere copiato o spostato, quindi è possibile salvare alcune connessioni nell'elenco e dopo un po 'di tempo, basta scorrere l'elenco e chiamare disconnect() per ogni oggetto. Esempio con una connessione:

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

Bonus: no, Qt non supporta tale introspezione profonda, non è possibile ottenere l'elenco di tutti gli slot collegate o qualcosa di altro, ma nella maggior parte dei casi, non è necessario questo affatto. Una informazione utile, che Qt ti dà è sender(), puntatore all'oggetto che ha inviato il segnale.

Modifica

Come doc detto:

Disconnetti tutto collegato ai segnali di un oggetto

Così, nel prossimo esempio verrà mostrato entrambe le finestre:

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"); 

Ma comparirà il commento a->disconnect(); e solo le finestre A. Significa che QObject::connect(b,SIGNAL(objectNameChanged(QString)),a,SLOT(show())); non è stato disconnesso come indicato nel doc. Se vuoi risolvere questo puzzle puoi fare a->disconnect(b);b->disconnect(a);, ma ovviamente è un approccio molto cattivo. Così si può utilizzare secondo suggerimento dalla mia risposta:

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

Risposta piacevole, disconnette tutto disconnettendo entrambe le connessioni in entrata e in uscita? – Troyseph

+1

@SebastianTroy Vedi la mia risposta modificata per favore. – Chernobyl

Problemi correlati