web-dev-qa-db-de.com

Erzwingen der Aktualisierung der Qt-GUI, bevor eine separate Funktion aufgerufen wird

Es scheint, als sollte es automatisch sein, aber offensichtlich nicht. Ich habe folgenden Code:

    ui.my_label->setText("Test 1...");
    ui.my_label->adjustSize();

    processThatTakesAbout30SecondsToFinish(files[0].toStdString());

    ui.my_label->setText("Finished.");
    ui.my_label->adjustSize();

Was passiert ist, dass ich niemals siehe "Test1...", scheint, da die GUI scheinbar hängen bleibt, bis die folgende Funktion abgeschlossen ist, und ich sehe nur "Fertig". 

Wie kann ich sicherstellen, dass die GUI aktualisiert wird, bevor diese Funktion aufgerufen wird?
Vielen Dank.

23
zebra

Sie können die Ereigniswarteschlange verarbeiten, bevor Sie Ihren Code eingeben, wenn Sie dies tun.

#include <QApplication>

und wenn Sie Ihre GUI aktualisieren möchten, rufen Sie an;

qApp->processEvents();

Beachten Sie, dass es eine gute Idee sein kann, Ihren langwierigen Prozess ab und zu diese Funktion aufrufen zu lassen, damit sich Ihre GUI schneller anfühlt.

26

Wenn Sie sich nicht dafür interessieren, dass Ihre GUI während dieser Zeit reagiert, ist ein Aufruf an my_label->repaint() der Trick. Qt kann nichts automatisch für Sie tun, wenn Sie der Ereignisschleife nachgeben.

Für eine maximale Reaktionsfähigkeit können Sie den Prozess in einem separaten Thread ausführen und Signal-/Slot-Verbindungen (die standardmäßig threadsicher sind) verwenden, um Ihren Haupt-GUI-Thread zu signalisieren, wenn Ihre Verarbeitung abgeschlossen ist.

14
Chris

Ich wollte nur hinzufügen, dass es für mich eine Kombination aus den beiden Antworten gab, die ich hier gesehen habe. Was für mich funktioniert hat, war:

ui.my_label->setText("Test 1...");
ui.my_label->adjustSize();

//! Both of these lines needed
ui.my_label->repaint();
qApp->processEvents();

processThatTakesAbout30SecondsToFinish(files[0].toStdString());

ui.my_label->setText("Finished.");
ui.my_label->adjustSize();

Hoffe das hilft jemandem.

3
Chuck Claunch

Funktion definieren ...

void YourClass::Update_Ui()
{
if(this->isEnabled())
    return;

this->repaint();
qApp->processEvents();
}

... so und stellen Sie sicher, dass this deaktiviert ist (um Benutzeraktionen zu verhindern), während Sie ein Update der ui erzwingen möchten, die beste Lösung für mich war.

Beispiel für die Verwendung innerhalb einer Funktion (z. B. während einer Stapelverarbeitung, die viel Zeit in Anspruch nimmt):

this->setEnabled(false);
//Do whatever you want
Update_Ui();
//Do some other stuff
this->setEnabled(true);

Dies erlaubt es dem Benutzer nicht, die Verarbeitung durch ui-Interaktion (es ist deaktiviert) zu stören und wird immer dann aktualisiert, wenn Update_Ui(); im Code aufgerufen wird und die gesamte ui-Datei aktualisiert, nicht nur ein ausgewähltes Label oder was auch immer. Beachten Sie, dass dies keine Signale blockiert, die von ui-Elementen ausgelöst werden.

0
Kemendil