2012-03-21 8 views
22

Qt documentation afferma che è possibile collegare due segnali insieme:Qt collegare due segnali insieme utilizzando QueuedConnection

È anche possibile collegare un segnale direttamente ad un altro segnale.

Ho provato:

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

e funziona come detto, ma la documentazione Qt continua: (. Questo emetterà il secondo segnale immediatamente quando il primo viene emesso)

Ciò significa che QueuedConnection non funzionerà correttamente? Posso collegare due segnali ai thread?

Il motivo che sto chiedendo questo è perché ho risolto una classe di incidenti su una domanda evitando questo, ma non sono sicuro se questo è stato legato al collegamento di segnali insieme.

+2

Hai provato la creazione di un banco di prova di connessioni segnale segnale di cross-threaded? Stampare un messaggio prima e dopo il segnale originale (in un thread) e in uno slot collegato al secondo segnale (in un secondo thread).Nel secondo thread, si chiama ripetutamente un 'sleep' che dura un secondo o due nel ciclo degli eventi, per rendere più ovvio che lo slot in quel thread venga chiamato in modo sincrono con il primo thread o in modo asincrono nel secondo thread. – tmpearce

+0

@ tmpearce- buon consiglio, proverò e posterò il risultato qui – dashesy

+2

Quindi, l'hai mai provato? – gnovice

risposta

24

Non dovrebbe essere molto diverso da una connessione segnale/slot. Diamo un'occhiata al meccanismo di base dei segnali/slot. C'è una coda di eventi in ogni thread che mantiene segnali (eventi) che sono stati emessi ma non ancora elaborati. Quindi, ogni volta che l'esecuzione ritorna al ciclo degli eventi, la coda viene elaborata. Lo stesso loop eventi non gestisce gli eventi. Piuttosto li consegna agli oggetti in modo che possano gestirli. In questo caso speciale, suppongo che l'oggetto emetterebbe un altro segnale che verrebbe inserito nella coda. Quando l'esecuzione ritorna al ciclo degli eventi, il nuovo segnale viene nuovamente gestito dall'oggetto. Ecco un test che dimostra l'argomento sopra.

Se si eseguono i codici allegati, l'output sarà:

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

che significa definire un tipo di connessione di segnale-segnale come coda tra fili hanno il comportamento coda previsto, che respinge l'argomento che è sempre immediato. Se lo definisci come diretto, l'output sarà:

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

come previsto. non genera errori o avvisi, e il programma non va in crash come well.Yet questo semplice esempio non prova che funziona per un grande e complesso come bene.

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"; 
}