2010-08-20 6 views

Antwort

41

Vor ein paar Wochen hatten wir einen Praktikanten versehentlich ein Signal mehr als einmal an einen Steckplatz anschließen. Die Idee war, dass Sie unter einer Bedingung den Steckplatz mit dem Signal verbunden haben und unter einer anderen Bedingung die Verbindung trennen würden. Wenn Sie den Modus gewechselt haben, haben Sie die entsprechende Arbeit geleistet.

Nun, er vergaß zu trennen, wenn es angebracht ist. Jedes Mal, wenn Sie den Modus änderten, hatten Sie eine neue Verbindung zum Slot.

Das Endergebnis? 1 Verbindung == 1 Anruf zum Steckplatz. 2 Verbindungen == 2 Anrufe zum Steckplatz. 3 Verbindungen == 3 Anrufe zum Slot usw. Diese Anrufe sind "simultan" passiert (ich weiß in Wirklichkeit nicht, da sie auf dem selben Event-Thread stehen, aber was ich meine war, dass alle Anrufe nacheinander abgearbeitet wurden).

Wie @Job in einem seiner Kommentare (er verdient Kredit, also bitte nicht upvote mich für seine Arbeit), Qt::UniqueConnection wird dieses Problem zu verhindern.

+1

+1: Dies ist das klassische Szenario. – Troubadour

+53

Beachten Sie, dass Sie [Qt :: UniqueConnection] (http://doc.trolltech.com/latest/qt.html#ConnectionType-enum) verwenden können, um dieses Szenario zu verhindern. – Job

+0

@Job: Ich würde eine Antwort damit hinzufügen. Mir war nicht bewusst, dass das zu Qt hinzugefügt wurde. Danke, dass du es aufgezeigt hast. – Troubadour

5

Normalerweise schlechte Dinge. Es ist vollkommen akzeptabel, den Slot zweimal oder noch öfter zu verbinden, aber wenn das Signal ausgelöst wird, wird Ihr Slot für jede Verbindung aufgerufen, die Sie wahrscheinlich nicht möchten.

Beachten Sie, dass es nicht unbedingt falsch ist, mehrere Verbindungen zu haben. Es gibt (wahrscheinlich) vollkommen gültige Anwendungen dafür. Sie sind ziemlich selten, ich kann mir bestimmt keine Zeit vorstellen, in der ich sie als Feature benutzt habe. Alle Situationen, an die ich mich erinnere, wo es eine Mehrfachverbindung gab, entpuppten sich eher als Fehler als beabsichtigt.

+0

Ok, Was genau ist es in der moc-Datei? Ist es nicht in der Lage, solche Szenarien von Programmierfehlern zu behandeln? – itapadar

+0

@itapadar: Ich denke nicht, dass sie versuchen, es zu verhindern, weil es nicht ein Fehler sein könnte. Ich habe vor nicht allzu langer Zeit einen Code geschrieben, der sich in einigen Situationen auf dieses Feature verlassen hat. – Troubadour

+0

@itapadar: Eigentlich beim Nachdenken habe ich es nicht als Feature überhaupt verwendet. Es erschien als ein Fehler und ich musste es umgehen. – Troubadour

5

Der Slot wird mehrmals ausgeführt (wie bereits erwähnt).

Einige weitere Hinweise:

  • In früheren Zeiten das Muster für „connect genau einmal“ in Fällen, in denen es vor, eine Verbindung gewesen sein konnte, war zum ersten Gespräch trennen und verbinden genau eine Verbindung zu erzwingen . Jetzt
  • , da 4.6, gibt es auch die elegantere Qt :: UniqueConnection finden http://doc.qt.io/qt-5/qt.html#ConnectionType-enum
+0

Ich bin mir nicht sicher, ob es eine elegantere Lösung ist. Normalerweise sollte der Code symmetrisch sein und wenn das nicht der Fall ist, dann ist das ein Fehler. Ich mache mir Sorgen, dass 'Qt :: UniqueConnection' verwendet werden könnte, um schlampigen asymmetrischen Code häufiger zu patchen, als er für andere Zwecke verwendet wird. – Troubadour

+0

Ja, man kann argumentieren, dass beide "Verbindung einmal" Ansätze sind nicht nett. OTOH, wenn du ein Objekt von einer anderen Stelle bekommst, möglicherweise mehrere Male das gleiche Objekt, und alles, was du tun musst, ist ein Signal (einmal) zu hören, dann ist die einzige andere Art, an die ich denken kann, Listen der Objekte, die Sie bereits gesehen haben. Nicht nett auch nicht. Und trennen(), connect() ist ein bisschen zerbrechlich, da man darauf achten muss, sie synchron zu halten, wenn sich etwas ändert. Also würde ich UniqueConnection bevorzugen. In der Praxis sehe ich weder "connect once" noch sehr oft, also scheint es kein großes Problem zu sein. –

+0

+1 für Zeiger auf Qt :: UniqueConnection (was ich vorher nicht wusste) –