IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Discussion :

Affichage trop tardif d'une fenêtre (QWidget)

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2008
    Messages : 52
    Par défaut Affichage trop tardif d'une fenêtre (QWidget)
    Bonjour à tous,

    J'ai réaliser une fenetre de chargement basique pour mon programme. Cette fenetre contient juste un label contenant le text "Chargement...". Elle doit s'ouvrir avant le traitement d'une certaine durée et doit se refermé juste après. Cette fonction qui réalise un traitement sur des données est executée lors d'un click sur bouton. (Signal/Slot).

    Mon problème est que cette fenêtre(QWidget) s'ouvre toujours après le traitement sur les données alors que je l'ai déclaré avant ce traitement. Comment se fait t-il?

    Voilà un bout de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void MainWindow :: traiterDonnees(){
     
          FenetreChargement *fChargement=new FenetreChargement(QString("Chargment..."),NULL); //Creation de la fenetre
          fChargement->show(); //Affichage de la fenetre
     
          while(/*Ce qu'on veut*/){
          //On fait des traitements sur données pendant 1 min par exemple
          }
     
          //fChargement->close(); //On ferme la fenetre
    }
    et mon constructeur de fenetre est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    FenetreChargement ::  FenetreChargement(QString messageInformation,QWidget *parent) :QWidget(parent) {
          this->setFixedSize(200,20);
          this->setWindowFlags(Qt::Tool);
     
          //On gere le message que l'on va afficher
          lMessageInfo=new QLabel(this);
          lMessageInfo->setText(messageInformation);
    }
    Pourquoi la fenêtre s'affiche toujours à la fin du traitement des données et non pas au début?
    Comment puis-je palier à ce problème?

    Merci à tous.

  2. #2
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2007
    Messages
    774
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 774
    Par défaut
    Pourquoi la fenêtre s'affiche toujours à la fin du traitement des données et non pas au début?
    Quand tu fais ->show(), ça va envoyer un évènement à un gestionnaire d'évènement (l'eventloop) en gros, et c'est lui qui gère quand il traitera cet évènement. En gros, il fait ça quand l'application est "en attente", hors vu que tu fais ton while, il finit ta fonction avant de gérer l'évènement.
    Comment puis-je palier à ce problème?
    Tu peux utiliser la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    QCoreApplication::processEvents();
    void QCoreApplication::processEvents ( QEventLoop:rocessEventsFlags flags = QEventLoop::AllEvents ) [static]

    Processes all pending events for the calling thread according to the specified flags until there are no more events to process.

    You can call this function occasionally when your program is busy performing a long operation (e.g. copying a file).

    In event you are running a local loop which calls this function continuously, without an event loop, the DeferredDelete events will not be processed. This can affect the behaviour of widgets, e.g. QToolTip, that rely on DeferredDelete events to function properly. An alternative would be to call sendPostedEvents() from within that local loop.

    Calling this function processes events only for the calling thread.

    Note: This function is thread-safe.

    See also exec(), QTimer, QEventLoop::processEvents(), flush(), and sendPostedEvents().
    En gros, ça force l'application a géré tous les évènements immédiatement. Normalement, ça devrait régler ton problème.

    G.

  3. #3
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    C'est là ou QtConcurrent::run (ou un thread mais c'est plus compliqué) prend tous son sens
    Ca ne bloque pas l'eventloop principale et donc ton IHM.
    L'appel de
    QCoreApplication::processEvents();
    si c'est mal utilisé, peut te plomber tout le temps de traitement ou t'affiché ta fenêtre en blanc. C'est une solution mais faut ni trop ni pas assez l'appeler.

    Y as aussi QProgressDialog, qui pourrais être intéressant dans ton cas:
    http://qt.developpez.com/doc/latest/...tion-detaillee

  4. #4
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2008
    Messages : 52
    Par défaut
    Tout d'abord, merci d'avoir répondu si vite.

    Je ne sais pas si j'ai bien compris comment il fallait faire pour résoudre ce problème. Toujours est il que j'ai modifié mon code de cette façon:

    Constructeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    FenetreChargement ::  FenetreChargement(QString messageInformation,QWidget *parent) :QWidget(parent) {
          this->setFixedSize(200,20);
          this->setWindowFlags(Qt::Tool);
     
          //On gere le message que l'on va afficher
          lMessageInfo=new QLabel(this);
          lMessageInfo->setText(messageInformation);
     
          this->show();
         QCoreApplication::processEvents();
    }
    Ma fenêtre s'affiche bien avant le traitement des données mais celle-ci ne contient rien,. Le label ne contient rien ou n'est pas afficher. Pourquoi?

    Autrement, j'avais essayé de creer ma fenetre via un tread mais cette derniere ne s'afichait que lorsque tous les traitements étaient terminer (à la fin de l'execution de la méthode). J'avais le même problème qu'avant.

    Merci de votre aide.

  5. #5
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par qhardy Voir le message
    Autrement, j'avais essayé de creer ma fenetre via un tread mais cette derniere ne s'afichait que lorsque tous les traitements étaient terminer (à la fin de l'execution de la méthode). J'avais le même problème qu'avant.
    C'est le traitement qu'il faut mettre dans un thread. QtConcurrent simplifie tout cela sans avoir besoin de créé un thread.

  6. #6
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2008
    Messages : 52
    Par défaut
    J'ai essayé de mettre mon traitement dans un thread via
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    QFuture<void> thread = QtConcurrent::run(this,&MainWindow ::traiterDonnees);
    thread.waitForFinished();
    mais il y a des erreurs qui apparaissent lors de de son execution: Il y a des élements que je ne peux pas axeder car private....C'est ce qui est marqué en tout cas.

    Y a t'il un autre moyen pour que ma fenetre de chargement s'affiche puis que lorsque la fenetre est bien affiché, les traitements commencent( sans utiliser les threads)? Du bon vieux mode séquentiel...
    Est ce possible avec QCoreApplication::processEvents(). Si oui,comment palier au faites que la fenetre s'affiche sans rien à l'interieur?

    Merci d'avance.

Discussions similaires

  1. GUI Affichage des axes dans une fenêtre de type 'axes'
    Par Matersss dans le forum Interfaces Graphiques
    Réponses: 2
    Dernier message: 09/03/2011, 12h52
  2. Affichage de texte dans une fenêtre
    Par whitebird001 dans le forum MFC
    Réponses: 3
    Dernier message: 19/05/2008, 00h22
  3. Affichage des résultats dans une fenêtre
    Par yoyo69 dans le forum MATLAB
    Réponses: 2
    Dernier message: 10/12/2007, 09h06
  4. pb affichage dans une fenêtre
    Par Mat 74 dans le forum Windows
    Réponses: 8
    Dernier message: 27/11/2005, 23h14
  5. Affichage d'images dans une fenêtre
    Par tonycalv dans le forum MFC
    Réponses: 6
    Dernier message: 20/04/2005, 20h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo