Qt conecta dos señales juntas usando QueuedConnection
thread-safety signals (2)
Echa un vistazo a qt-project, es una gran página wiki sobre Hilos y señales.
Threads, Events y QObjects :: Signals and slots across threads
La documentation Qt indica que es posible conectar dos señales juntas:
Incluso es posible conectar una señal directamente a otra señal.
Lo intenté:
connect(x, SIGNAL(S()), y, SIGNAL(func()));
y funciona como se mencionó, pero la documentación de Qt continúa:
(Esto emitirá la segunda señal inmediatamente cada vez que se emita la primera).
¿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 de si esto estuvo relacionado con la conexión de señales entre sí.
No debería 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 adjuntos, la salida sería:
before signal()
after signal()
slot() called
lo que significa que la definición de un tipo de conexión de señal de señal como en cola entre hilos tiene el comportamiento en cola esperado, 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";
}