La causa y solución del problema de que la función de ranura Qt se ejecutará varias veces

Hay 3 formas de resolver este problema:

1. Conéctese solo en la función de inicialización

Debido a que la función de inicialización solo se ejecuta una vez en todo el programa, conectar señales y ranuras aquí puede evitar problemas de conexión repetidos.

2. Después de activar la función de ranura, desconecte la función de ranura (este método puede realizar una conexión dinámica)


 QMetaObject::Connection connectHandler = connect(pBtn, &QAbstractButton::clicked, this, &QtWidgetsApplication2::btnClicked); // Desconectar la
 
primera
desconexión(connectHandler); 
 
// Volver a
conectar connect(pBtn, &QAbstractButton::clicked, this, &QtWidgetsApplication2 ::btnClicked );

3. Escribe el parámetro Qt::UniqueConnection en la función de conexión.


La función de Qt::UniqueConnection es: si la señal no se ha conectado antes, conéctela y devuelve verdadero, si se ha conectado antes, ya no estará conectada y devuelve falso. Por ejemplo connect(ui.btn, &QAbstractButton::clicked, this, &QtWidgetsApplication2::btnClicked, Qt::UniqueConnection);

conectar el quinto parámetro

Hay cinco quintos parámetros:

1.Qt::AutoConnection : Valor predeterminado. Usando este valor, el tipo de conexión se determinará cuando se envíe la señal. El juicio es el siguiente: Si la ubicación de recepción y envío de la señal están en el mismo hilo, el El tipo Qt::DirectConnection se utilizará automáticamente. Si las señales de recepción y envío no están en el mismo hilo, se utiliza automáticamente el tipo Qt::QueuedConnection.

PD:

QThread *startThread = new QThread();
    //El hilo donde se encuentra la emisión de la señal es diferente del hilo donde se encuentra la función de ranura. AutoConnect es una función de ranura de conexión de cola y no se ejecuta en el hilo. Debe ser especificado como una conexión directa que se ejecutará en el hilo del remitente.
    connect(startThread, SIGNAL(started()), this, SLOT(Test()),);
    startThread->start();

Como en el ejemplo anterior, Test() es una función de ranura de la interfaz de usuario principal. Obviamente, la señal Qthread::started y Test() no están en el mismo hilo, por lo que finalmente se utiliza el método de conexión de cola y la función Test() se ejecutará en la interfaz de usuario principal. Piense que si desea que la función de prueba se ejecute en un hilo, el parámetro 5 debe especificarse como Qt::DirectConnection.


2.Qt::DirectConnection : La función de ranura se llamará directamente cuando se envíe la señal. La función de ranura se ejecuta en el hilo del remitente de la señal. La función de ranura está en el hilo de quien emite la señal. El efecto parece como si la función de ranura se llamara directamente en el lugar donde se envía la señal. Esto es más peligroso en un entorno de subprocesos múltiples y puede causar fallas porque habrá problemas con el acceso entre subprocesos. Esto puede entenderse como ejecución sincrónica. El código después de la declaración de emisión se ejecutará después de que se hayan ejecutado todas las funciones de la ranura. . (La relación entre señales y funciones de ranura es similar a las llamadas a funciones, ejecutadas sincrónicamente)

3.Qt::QueuedConnection : La función de ranura se llama cuando el control regresa al bucle de eventos del hilo donde se encuentra el receptor. La función de ranura se ejecuta en el hilo donde se encuentra el receptor de señal. Quien reciba la señal estará en en cuyo hilo se encuentra la función de ranura. Después de enviar la señal, la función de ranura no se llamará inmediatamente y no se llamará hasta que se ejecute la función actual del receptor y se ingrese al bucle de eventos. Esto se usa generalmente en entornos de subprocesos múltiples y puede entenderse como ejecución asincrónica. El código después de la declaración de emisión se ejecutará inmediatamente después de que se envíe la señal, sin esperar a que la función de ranura complete su ejecución. (En este momento, la señal se introduce en la cola de señales. La relación entre la señal y la función de ranura es similar a la comunicación de mensajes y la ejecución asincrónica)


4.Qt::BlockingQueuedConnection : El tiempo de llamada de la función de ranura es el mismo que Qt::QueuedConnection, pero después de enviar la señal, el hilo del remitente se bloqueará, lo que equivale a una sincronización de simulación asíncrona hasta que la función de ranura termine de ejecutarse. . El receptor y el remitente no deben estar en el mismo hilo; de lo contrario, el programa se bloqueará. Esto puede ser necesario cuando se requiere sincronización entre varios subprocesos.


5.Qt::UniqueConnection : este indicador se puede utilizar en combinación con los cuatro anteriores mediante OR bit a bit (|). Cuando se establece este indicador, cuando una señal y una ranura ya están conectadas, las conexiones repetidas fallarán. Eso es para evitar conexiones repetidas.
 

Supongo que te gusta

Origin blog.csdn.net/m0_52467164/article/details/131069560
Recomendado
Clasificación