2012-03-21 18 views
22

Qt documentation establece que es posible conectar dos señales juntas:Qt conectar dos señales juntas utilizando QueuedConnection

Incluso es posible conectar una señal directamente a otra señal.

me trataron:

connect(x, SIGNAL(S()), y, SIGNAL(func())); 

y funciona como se ha mencionado, pero la documentación de Qt sigue: (. Esto va a emitir la segunda señal inmediatamente cuando la primera se emite)

¿Esto significa que QueuedConnection no funcionará correctamente? ¿Puedo conectar dos señales a través de hilos?

La razón por la que estoy preguntando esto es porque resolví una clase de bloqueos en una aplicación al evitar esto, pero no estoy seguro si esto estuvo relacionado con la conexión de señales entre sí.

+2

Ha intentado crear un caso de prueba de las conexiones de señal de la señal cruzada de rosca? Imprima un mensaje antes y después de la señal original (en un hilo) y en un espacio conectado a la segunda señal (en un segundo hilo).En el segundo hilo, llama repetidamente a un 'sueño' que dura uno o dos segundos en el bucle de evento, para que sea más obvio que el intervalo en ese hilo se está llamando de forma síncrona con el primer hilo o asincrónicamente en el segundo hilo. – tmpearce

+0

@ tmpearce- buen consejo, lo intentaré y publicaré el resultado aquí – dashesy

+2

Entonces, ¿alguna vez lo intentó? – gnovice

Respuesta

24

No debe ser muy diferente de una conexión de señal/ranura. Echemos un vistazo al mecanismo subyacente de las señales/ranuras. Hay una cola de eventos en cada hilo que mantiene señales (eventos) que se han emitido pero aún no se han procesado. Por lo tanto, cada vez que la ejecución vuelve al bucle de evento, la cola se procesa. El bucle de eventos en sí no maneja los eventos. Más bien, los entrega a los objetos para que puedan manejarlo. En este caso especial, supongo que el objeto emitiría otra señal que se insertaría en la cola. Cuando la ejecución vuelve al bucle de evento, el objeto maneja la nueva señal de nuevo. Aquí hay una prueba que prueba el argumento anterior.

Si ejecuta los códigos que se adjunta, la salida sería:

before signal() 
after signal() 
slot() called 

que significa definir un tipo de conexión de señal de la señal como la cola entre las roscas tienen el comportamiento en cola era de esperar, que rechaza el argumento que siempre es inmediato. Si lo define como directo, la salida sería:

before signal() 
slot() called 
after signal() 

como se esperaba. no genera ningún error ni advertencia, y el programa no falla también. Sin embargo, este simple ejemplo no prueba que también funcione para uno grande y complejo.

main.cpp:

#include <QtGui/QApplication> 
#include "dialog.h" 
#include "testssconnection.h" 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 

    TestSignalSignalConnection * t = new TestSignalSignalConnection(); 
    t->start(); 

    return a.exec(); 
} 

testssconnection.h:

#ifndef TESTSSCONNECTION_H 
#define TESTSSCONNECTION_H 

#include <QObject> 
#include <QThread> 

class TestSignalSignalConnection : public QThread 
{ 
    Q_OBJECT 
public: 
    explicit TestSignalSignalConnection(QObject *parent = 0); 

    void run(); 

signals: 
    void signal1(); 
    void signal2(); 

public slots: 
    void slot(); 
}; 

#endif // TESTSSCONNECTION_H 

testssconnection.cpp:

#include "testssconnection.h" 
#include <QtCore> 

TestSignalSignalConnection::TestSignalSignalConnection(QObject *parent) : 
    QThread(parent) 
{ 
} 

void TestSignalSignalConnection::run() 
{ 
    TestSignalSignalConnection *t = new TestSignalSignalConnection(); 

    this->connect(this,SIGNAL(signal1()),t,SIGNAL(signal2()), Qt::QueuedConnection); 
    t->connect(t,SIGNAL(signal2()), t,SLOT(slot()), Qt::DirectConnection); 

    qDebug() << "before signal()"; 
    emit signal1(); 
    qDebug() << "after signal()"; 

    exec(); 
} 

void TestSignalSignalConnection::slot() 
{ 
    qDebug() << "slot() called"; 
}