30 votes

Forcer la mise à jour de l'interface graphique Qt avant d'entrer dans une fonction séparée

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

La situation est telle que je ne vois jamais "Test1...", car l'interface graphique semble se bloquer jusqu'à ce que la fonction suivante soit terminée, et je ne vois finalement que "Finished.".

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

32voto

Joachim Isaksson Points 85969

Vous devriez être capable de traiter la file d'événements avant d'entrer dans votre code si vous;

#include 

et, lorsque vous voulez rafraîchir votre GUI, appelez;

qApp->processEvents();

Notez qu'il peut être une bonne idée de laisser votre processus long appeler cette fonction de temps en temps, pour rendre votre GUI plus réactive.

16voto

Chris Points 7557

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 à moins que vous ne cédiez la boucle d'événements.

Pour une réactivité maximale, vous pourriez envisager d'exécuter votre processus dans un thread séparé et d'utiliser des connexions signal/slot (qui sont par défaut thread-safe) pour signaler à votre thread GUI principal lorsque votre traitement est terminé.

3voto

Chuck Claunch Points 856

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

//! Les deux lignes ci-dessus étaient nécessaires
ui.my_label->repaint();
qApp->processEvents();

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

ui.my_label->setText("Terminé.");
ui.my_label->adjustSize();

J'espère que cela aidera quelqu'un.

1voto

Kemendil Points 73

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) lorsque vous voulez forcer une mise à jour de l'ui était la meilleure solution pour moi.

Exemple d'utilisation à l'intérieur d'une fonction (par exemple lors d'un traitement de pile qui prend beaucoup de temps):

this->setEnabled(false);
//Faites ce que vous voulez
Update_Ui();
//Faites autre chose
this->setEnabled(true);

Cela ne permet pas à l'utilisateur de perturber le traitement par une interaction avec l'ui (il est désactivé) et met à jour chaque fois que Update_Ui(); est appelé dans le code et met à jour tout l'ui, pas seulement un label choisi ou autre chose. Notez que cela ne bloque pas les signaux émis par les éléments ui.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X