Die Ursache und Lösung des Problems, dass die Qt-Slot-Funktion mehrmals ausgeführt wird

Es gibt drei Möglichkeiten, dieses Problem zu lösen:

1. Verbinden Sie sich nur in der Initialisierungsfunktion

Da die Initialisierungsfunktion im gesamten Programm nur einmal ausgeführt wird, können durch die Verbindung von Signalen und Steckplätzen wiederholte Verbindungsprobleme vermieden werden.

2. Nachdem die Slot-Funktion ausgelöst wurde, trennen Sie die Slot-Funktion (diese Methode kann eine dynamische Verbindung realisieren).


 QMetaObject::Connection connectHandler = connect(pBtn, &QAbstractButton::clicked, this, &QtWidgetsApplication2::btnClicked); //
 
Trennen Sie zuerst
die Verbindung interrupt(connectHandler); 
 
// Wiederverbinden
connect(pBtn, &QAbstractButton::clicked, this, &QtWidgetsApplication2 ::btnClicked );

3. Schreiben Sie den Parameter Qt::UniqueConnection in die Verbindungsfunktion


Die Funktion von Qt::UniqueConnection lautet: Wenn das Signal noch nicht verbunden war, verbinden Sie es und geben Sie true zurück. Wenn es zuvor verbunden war, ist es nicht mehr verbunden und gibt false zurück. Zum Beispiel connect(ui.btn, &QAbstractButton::clicked, this, &QtWidgetsApplication2::btnClicked, Qt::UniqueConnection);

Verbinden Sie den fünften Parameter

Es gibt fünf fünfte Parameter:

1.Qt::AutoConnection : Standardwert. Mit diesem Wert wird der Verbindungstyp bestimmt, wenn das Signal gesendet wird. Die Beurteilung lautet wie folgt: Wenn sich der Ort des Signalempfangs und des Signalsendes im selben Thread befinden, wird der Der Typ Qt::DirectConnection wird automatisch verwendet. Wenn sich die Empfangs- und Sendesignale nicht im selben Thread befinden, wird automatisch der Typ Qt::QueuedConnection verwendet.

PS:

QThread *startThread = new QThread();
    // Der Thread, in dem sich die Signalausgabe befindet, unterscheidet sich von dem Thread, in dem sich die Slot-Funktion befindet. AutoConnect ist eine Slot-Funktion für die Warteschlangenverbindung und wird nicht im Thread ausgeführt. Das muss so sein als direkte Verbindung angegeben, die im Thread des Absenders ausgeführt werden soll.
    connect(startThread, SIGNAL(started()), this, SLOT(Test()),);
    startThread->start();

Wie im obigen Beispiel ist Test() eine Slot-Funktion der Hauptbenutzeroberfläche. Offensichtlich befinden sich das Qthread::started-Signal und Test() nicht im selben Thread, sodass schließlich die Warteschlangenverbindungsmethode und die Funktion Test() verwendet werden wird in der Hauptbenutzeroberfläche ausgeführt. Wenn Sie möchten, dass die Testfunktion in einem Thread ausgeführt wird, muss Parameter 5 als Qt::DirectConnection angegeben werden.


2.Qt::DirectConnection : Die Slot-Funktion wird direkt aufgerufen, wenn das Signal gesendet wird. Die Slot-Funktion läuft im Thread des Signalsenders. Die Slot-Funktion befindet sich im Thread desjenigen, der das Signal aussendet. Der Effekt sieht so aus, als würde die Slot-Funktion direkt an der Stelle aufgerufen, an die das Signal gesendet wird. Dies ist in einer Multithread-Umgebung gefährlicher und kann zu einem Absturz führen, da es zu Problemen beim Cross-Thread-Zugriff kommt. Dies kann als synchrone Ausführung verstanden werden. Der Code nach der Emit-Anweisung wird ausgeführt, nachdem alle Slot-Funktionen ausgeführt wurden . (Die Beziehung zwischen Signalen und Slot-Funktionen ähnelt Funktionsaufrufen, die synchron ausgeführt werden.)

3.Qt::QueuedConnection : Die Slot-Funktion wird aufgerufen, wenn die Steuerung zur Ereignisschleife des Threads zurückkehrt, in dem sich der Empfänger befindet. Die Slot-Funktion wird in dem Thread ausgeführt, in dem sich der Signalempfänger befindet. Wer das Signal empfängt, wird dabei sein in dessen Thread sich die Slot-Funktion befindet. Nach dem Senden des Signals wird die Slot-Funktion nicht sofort aufgerufen, sondern erst, wenn die aktuelle Funktion des Empfängers ausgeführt und in die Ereignisschleife eingetreten wird. Dies wird im Allgemeinen in Multithread-Umgebungen verwendet und kann als asynchrone Ausführung verstanden werden. Der Code nach der Emit-Anweisung wird sofort nach dem Senden des Signals ausgeführt, ohne darauf zu warten, dass die Slot-Funktion die Ausführung abschließt. (Zu diesem Zeitpunkt wird das Signal in die Signalwarteschlange gestopft. Die Beziehung zwischen dem Signal und der Slot-Funktion ähnelt der Nachrichtenkommunikation und der asynchronen Ausführung.)


4.Qt::BlockingQueuedConnection : Der Aufrufzeitpunkt der Slot-Funktion ist derselbe wie der von Qt::QueuedConnection, aber nach dem Senden des Signals wird der Thread des Absenders blockiert, was einer asynchronen Simulationssynchronisation bis zur Slot-Funktion entspricht beendet den Lauf. Empfänger und Sender dürfen sich nicht im selben Thread befinden, da sonst das Programm blockiert. Dies kann erforderlich sein, wenn eine Synchronisierung zwischen mehreren Threads erforderlich ist.


5.Qt::UniqueConnection : Dieses Flag kann in Kombination mit den oben genannten vier durch bitweises ODER (|) verwendet werden. Wenn dieses Flag gesetzt ist und ein Signal und ein Steckplatz bereits verbunden sind, schlagen wiederholte Verbindungen fehl. Dadurch sollen wiederholte Verbindungen vermieden werden.
 

Ich denke du magst

Origin blog.csdn.net/m0_52467164/article/details/131069560
Empfohlen
Rangfolge