Nie powinno to być nic innego niż połączenie sygnału/gniazda. Rzućmy okiem na ukryty mechanizm sygnałów/gniazd. W każdym wątku znajduje się kolejka zdarzeń, która utrzymuje sygnały (zdarzenia), które zostały wyemitowane, ale jeszcze nie przetworzone. Tak więc, gdy wykonanie powraca do pętli zdarzeń, przetwarzana jest kolejka. Sama pętla zdarzeń nie obsługuje zdarzeń. Raczej dostarcza je do obiektów, aby mogli sobie z tym poradzić. W tym szczególnym przypadku, przypuszczam, że obiekt wyemitowałby inny sygnał, który zostałby wstawiony do kolejki. Kiedy wykonanie powraca do pętli zdarzeń, nowy sygnał jest ponownie obsługiwany przez obiekt. Oto test, który potwierdza powyższy argument.
Jeśli prowadzisz kody dołączone wyjście byłoby:
before signal()
after signal()
slot() called
co oznacza zdefiniowanie typu połączenia sygnału sygnału w kolejce pomiędzy wątkami są oczekiwane w kolejce zachowanie, które odrzuca argument, który jest zawsze natychmiastowy. Jeśli zdefiniujesz to jako bezpośrednie, wyjście będzie:
before signal()
slot() called
after signal()
zgodnie z oczekiwaniami. nie generuje żadnych błędów ani ostrzeżeń, a program również się nie psuje. Ten prosty przykład nie dowodzi, że działa również dla dużego i złożonego.
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";
}
Czy próbowałeś tworzenia przypadków testowych połączeń poprzecznych gwintowane sygnał sygnał? Wydrukuj komunikat przed i po oryginalnym sygnale (w jednym wątku) oraz w gnieździe połączonym z drugim sygnałem (w drugim wątku).W drugim wątku wielokrotnie wywołuj "uśpienie" trwające sekundę lub dwie w pętli zdarzeń, aby było bardziej oczywiste, że szczelina w tym wątku jest wywoływana albo synchronicznie z pierwszym wątkiem, albo asynchronicznie w drugim wątku. – tmpearce
@ tmpearce- dobra rada, spróbuję i opublikuję tutaj wynik – dashesy
Czy kiedykolwiek próbowałeś? – gnovice