7 Stimmen

Problem mit Qt::QueuedConnection, Signal wird nach Verbindungsabbruch geliefert

Ich habe gerade ein interessantes Verhalten der Warteschlangenverbindung in Qt 4.6 entdeckt:

Die erste Verbindung in der Warteschlange wird hergestellt:

connect(someSender, SIGNAL(completed()), this, SLOT(handleCompletion()), Qt::QueuedConnection)

Dann sendet someSender das Signal:

emit completed()

Bevor ich das Signal empfange (da es sich in der Warteschlange befindet), trenne ich die Verbindung zum Signal:

disconnect(someSender, SIGNAL(completed()), this, SLOT(handleCompletion())

Dennoch wird der Slot handleCompletion bei der nächsten Iteration der Ereignisschleife aufgerufen. Ich kann dies verhindern, indem ich someSender->blockSignals(true) an der richtigen Stelle verwende, aber es fühlt sich schrecklich an, nicht zu erwähnen, dass ich ein boolesches Flag habe, um die Funktionalität des Slots zu deaktivieren.

Insbesondere bin ich erstaunt, dass dieses Verhalten nicht in der Qt-Dokumentation erwähnt wird (zumindest habe ich es nicht gefunden).

Schließlich die Frage: Gibt es eine sinnvolle Möglichkeit, dies zu verhindern?

9voto

rohanpm Punkte 4194

Ich denke, Qt verhält sich auf die intuitivste Weise.

Wenn Sie das tun emit completed() ist es sinnvoll, dass das Signal alle angeschlossenen Steckplätze sofort aktiviert oder in eine Warteschlange stellt. Könnten in die Warteschlange eingereihte Slots als Folge einer Verbindungsunterbrechung wieder freigegeben werden, wäre dies schwieriger zu verstehen und anfälliger für Race Conditions. Man sollte auch komplexere Szenarien in Betracht ziehen: Wenn z. B. eine Verbindung getrennt wird, wird sie dann wieder in die Warteschlange gestellt?

Wenn es so funktionieren würde, wie Sie es erwartet haben, würde anstelle dieser Frage "Problem mit Qt::QueuedConnection, signal not delivered after disconnect" stehen.

Um dies zu vermeiden, sollten Sie Ihren Code so umgestalten, dass es weder für den Sender noch für den Empfänger von Bedeutung ist, ob das Signal direkt verbunden ist oder in einer Warteschlange steht. Ich würde empfehlen, dass weder der Sender noch der Empfänger QObject::connect und dies wird von einer dritten Klasse durchgeführt. Es ist nicht klar, ob dies Ihr Problem vollständig lösen wird, es hängt davon ab, wo und warum Sie die disconnect .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X