2016-08-11 5 views
0

Ich schreibe ein Programm für die Interaktion mit einer Netzwerk-basierten API mit Qt. Die Interaktion mit der API erfolgt mit XML-Nachrichten (sowohl Abfragen als auch Ergebnisse)GUI beim Warten auf QTcpSocket-Daten blockieren

Ich habe die Kommunikation und Datenverarbeitung in einer Klasse in einem Projekt der gemeinsamen Bibliothek implementiert und ich habe ein QMainWindow, in dem der Benutzer die Verbindungsdetails eingeben kann . Wenn Sie auf die Verbindungsschaltfläche klicken, sollte Folgendes passieren: 1. Eine Instanz der Verbindungsklasse wird erstellt. 2. Eine Verbindungsnachricht wird an die API gesendet, um die Sitzungs-ID abzurufen. Die Antwort wird analysiert und eine Sitzungs-ID wird in der Klasseninstanz gespeichert. 3. Eine Nachricht wird an die API gesendet, um einige Feldinformationen zu erhalten. Das XML wird dann analysiert, um die erforderlichen Feldinformationen zu extrahieren, um Daten von der API zu erhalten. 4. Eine weitere Nachricht wird gesendet, um die Daten zu erhalten, die den Feldern entsprechen. Die XML-Antwort wird dann analysiert und in einer Datenstruktur zur Verarbeitung gespeichert. 5. Die Daten werden dann verarbeitet und dem Benutzer angezeigt.

Ich machte ein einfaches Konsolenprogramm zum Testen der Bibliothek und es funktioniert gut - keine Nachricht wird gesendet, bevor alle Daten aus der vorherigen Nachricht verarbeitet wurden. Wenn ich denselben Prozess in einer QMainWindow-Instanz implementiere, tritt jedoch keine Wartezeit auf und Nachrichten werden nacheinander ohne Warten gesendet.

Wie kann ich den GUI-Thread blockieren, um auf die vollständige Verarbeitung zu warten, bevor die nächste Nachricht gesendet wird?

Dank

+2

Sie sollten den GUI-Thread nicht blockieren. Überarbeiten Sie Ihren Code, um zu sehen, an welchem ​​Ereignis Sie die nächste Nachricht senden. Wenn es angemessen ist, verschiebe den gesamten TCP-Sende/Empfangs-Code an einen anderen Thread. – Matt

+0

Ich weiß, dass ich den GUI-Thread im Allgemeinen nicht blockieren sollte, aber in diesem Fall muss ich, weil die extrahierten Daten vor dem Rendern verarbeitet werden müssen. Ich möchte nicht, dass der Benutzer den Prozess unterbrechen kann. – FredCpp

+0

Und wenn er wirklich muss? Verwenden Sie einen Popup-Dialog oder blocken Sie relevante GUI-Elemente einzeln. Genau wie alle Apps. – Matt

Antwort

2

die UI Sperrung wird durch die Blockierung der Ereignisschleife nicht erreicht. Es wird getan, indem Sie die Widgets zu deaktivieren, die Sie nicht wollen, Interaktion zu ermöglichen, mit - entweder durch buchstäblich Aufruf disable() Methode auf sie, oder durch die Interaktion Bewachung basierend auf einigen Zustandsvariablen, wie zB:

connect(button, &QPushButton::clicked, button, [this]{ 
    if (! hasAllData) return; 
    // react to a button press 
}); 

Alles, was Sie brauchen, ist Definieren Sie eine Reihe von Zuständen, in denen sich Ihre Anwendung befinden kann, und deaktivieren Sie relevante Widgets in den entsprechenden Zuständen. Ich gehe davon aus, dass es am schnellsten ist, alle Abfragen parallel auszuführen, sobald die Sitzung eingerichtet ist, und asynchron die Benutzeroberfläche zu aktualisieren, wenn die Antworten in Echtzeit zurückgegeben werden.

Verwandte Themen