ich die folgende Einstellung haben:QThread interthread Kommunikation: seltsames Verhalten Anschluss an & QThread :: beenden zu einem Lambda-vs Anschluss [& thread] {Gewinde-> quit();}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// Create the DBManager that will live for the entire
// duration of the application
auto dbManagerThread = std::make_unique<QThread>();
auto dbManager = std::make_unique<DBManager>();
dbManager->moveToThread(dbManagerThread.get());
dbManagerThread->start();
// for the initialization of the application, create the
// InitHelper object that will utilize the DBManager
auto initHelper = new InitHelper();
auto initHelperThread = new QThread();
initHelper -> moveToThread(initHelperThread);
// wire InitHelper and its thread
QObject::connect(initHelperThread, &QThread::started, initHelper, &InitHelper::run);
QObject::connect(initHelper, &InitHelper::finished, [&initHelperThread] { initHelperThread->quit();});
QObject::connect(initHelper, &InitHelper::finished, initHelper, &InitHelper::deleteLater);
QObject::connect(initHelperThread, &QThread::finished, initHelperThread, &QThread::deleteLater);
// wire InitHelper and DBManager
QObject::connect(initHelper, &InitHelper::queryDB, dbManager.get(), &DBManager::processQuery);
QObject::connect(dbManager.get(), &DBManager::queryResult, initHelper, &InitHelper::processQueryResult);
// block until all information is gathered
initHelperThread->start();
initHelperThread->wait();
std::cout << "Initialization completed." << std::endl;
// cleanup
dbManagerThread->quit();
QObject::connect(dbManagerThread.get(), &QThread::finished, &a, &QCoreApplication::quit);
return a.exec();
}
Die Idee ist, dass ich Haben Sie den DBManager, der asynchrone Datenbankzugriffe durchführt und somit in der gesamten Anwendung verwendet wird. Während der Initialisierung der Anwendung muss ich einige Informationen aus der Datenbank abrufen und dafür den bereits vorhandenen DBManager verwenden.
Da ich jedoch die Informationen aus der Datenbank benötige, um alle anderen Objekte zu erstellen, möchte ich die weitere Ausführung des Hauptthreads blockieren, bis mein InitHelper alle erforderlichen Informationen aus dem DBManager abgerufen hat.
Da der obige Code genau das tut, was er soll, glaube ich nicht, wie genau InitHelper und DBManager implementiert sind und ich habe sie hier weggelassen.
Was ich verwirrend finde, ist die Tatsache, dass ich das Lambda in der zweiten Zeile im 'wire InitHelper und sein Thread' Teil verwenden muss. Wenn ich ersetzen
QObject :: connect (initHelper, & InitHelper :: fertig, [& initHelperThread] {initHelperThread-> quit();});
von
QObject :: connect (initHelper, & InitHelper :: fertig, initHelperThread, & QThread :: beenden);
anscheinend der Thread nie heruntergefahren und so "Initialisierung abgeschlossen" wird nie auf stdout gedruckt werden.
Dies ist der Ausgang, wenn die Verbindung mit dem Lambda mit:
InitHelper: Initialization started...
DBManager: processing query...
InitHelper: processing query result
Initialization completed.
während, wenn sie direkt an den Schlitz verbindet, erhalte ich diese Ausgabe:
InitHelper: Initialization started...
DBManager: processing query...
InitHelper: processing query result
Kennt jemand warum es liegt Unterschied beim Anschluss an das Lambda, anstatt direkt mit dem Steckplatz zu verbinden? Und wie kann ich die Verbindung ohne ein Lambda schreiben?
Sie haben Recht, das Hinzufügen Qt :: Direct zum connect Anruf geschlitzten nur funktioniert gut. – Corristo
Ich habe eine Bearbeitung hinzugefügt, ich habe etwas ähnliches gesehen, es könnte schneller für Sie sein:) –
Ich denke, nur das Hinzufügen von Qt :: DirectConnect ist der einfachste Weg. Das Ausführen von a.exec() vor dem wait() funktioniert nicht. – Corristo