web-dev-qa-db-fra.com

Forcer l'interface graphique de Qt à se mettre à jour avant d'entrer dans une fonction distincte

Cela semble être automatique, mais apparemment ce n’est pas le cas. J'ai le code suivant:

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

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

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

Ce qui se passe, c’est que je jamais vois "Test1...", car l’interface graphique semble se bloquer jusqu’à ce que la fonction suivante soit terminée, et je ne vois éventuellement plus que "Terminé". 

Comment puis-je m'assurer que l'interface graphique est mise à jour avant d'entrer dans cette fonction?
Merci.

23
zebra

Vous devriez pouvoir traiter la file d’événements avant de saisir votre code si vous le souhaitez.

#include <QApplication>

et, lorsque vous souhaitez actualiser votre interface graphique, appelez;

qApp->processEvents();

Notez que cela peut être une bonne idée de laisser votre processus de longue durée appeler cette fonction de temps en temps, pour que votre interface graphique se sente plus réactive.

26
Joachim Isaksson

Si vous ne vous souciez pas de la réactivité de votre interface graphique pendant ce temps, alors un appel à my_label->repaint() ferait l'affaire. Qt ne peut rien faire automatiquement pour vous sauf si vous cédez à la boucle d'événement.

Pour une réactivité maximale, vous pouvez envisager d'exécuter votre processus dans un thread séparé et d'utiliser des connexions signal/slot (sécurisées pour les threads par défaut) pour signaler à votre thread d'interface graphique principal la fin du traitement.

14
Chris

Je voulais juste ajouter que pour moi, il a fallu combiner les deux réponses que j'ai vues ici. Donc, ce qui a fonctionné pour moi était:

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();

J'espère que ça aide quelqu'un.

3
Chuck Claunch

Définir une fonction ...

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

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

... comme ceci et assurez-vous que this est désactivé (pour empêcher les actions de l'utilisateur) alors que vous voulez forcer une mise à jour de ui était la meilleure solution pour moi.

Exemple d'utilisation dans une fonction (par exemple lors d'un traitement de pile prenant beaucoup de temps):

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

Cela ne permet pas à l'utilisateur de perturber le traitement par une interaction ui (cette option est désactivée) et se met à jour chaque fois que Update_Ui(); est appelé dans le code et met à jour la totalité de la ui, pas seulement une étiquette choisie. Notez que cela ne bloque pas les signaux déclenchés par des éléments ui.

0
Kemendil