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

Multithreading Discussion :

QThread et wait dialog


Sujet :

Multithreading

  1. #1
    Nouveau Candidat au Club
    Inscrit en
    Juin 2008
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 5
    Points : 1
    Points
    1
    Par défaut QThread et wait dialog
    Bonjour,

    Je rencontre en ce moment des problèmes de développement relatifs au multithreading sous Qt 4.3.4, j'aimerais avoir votre avis sur la question:

    Il s'agit de créer une wait dialog au sein d'une application. Celle ci doit faire défiler une suite d'image PNG en actualisant un timer au fil du temps, tandis qu'une opération lourde se produit (chargement de données, export).
    J'ai donc créé une classe dérivé de QThread qui envoit un signal au GUI thread pour l'actualiser. Le problème est que le slot du GUI thread n'est appelé qu'à la fin de l'opération. En utilisant Qt:irectConnection pour connecter directement le thread au GUI thread, j'ai pour résultat que la méthode d'update qui actualise la wait dialog est alors appelé depuis ce thread (au lieu du GUI thread comme c'était le cas avec Qt::AutoConnection par default), ce qui provoque un crash.

    Je précise que lorsque j'utilise Qt::AutoConnection par défault pour le connect, j'arrive à afficher la suite de png lorsque le GUI thread est libre.

    La question est finalement comment libérer le GUI thread des opérations qu'il est en train de réaliser à une fréquence donnée pour lui faire réaliser d'autres opérations. Avec un timer dans le GUI thread le résultat est le même.

    En parcourant le forum, je n'ai pas trouvé de solutions à ce problème.

    Si vous avez des pistes, merci de m'éclaircir

    Cdt,

    Coco

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Salut
    En utilisant Qt:irectConnection pour connecter directement le thread au GUI thread, j'ai pour résultat que la méthode d'update qui actualise la wait dialog est alors appelé depuis ce thread (au lieu du GUI thread comme c'était le cas avec Qt::AutoConnection par default), ce qui provoque un crash.
    Ce doit même être un assert non?

    Pourquoi as tu besoin d'un thread??? un QTimer suffirait largement

  3. #3
    Nouveau Candidat au Club
    Inscrit en
    Juin 2008
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 5
    Points : 1
    Points
    1
    Par défaut Oups
    "Warning: Slots that generate window system events or use window system functions must not be connected to a signal that is emitted from a thread that is not the GUI thread."

    Sans résoudre quoi que soit, ça m'indique que ma manière de procéder était crado

  4. #4
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 033
    Points : 13 968
    Points
    13 968
    Par défaut
    EN gros, JAMAIS DE TRAITEMENT GUI DANS UNE THREAD.
    Hors que tu oblige une connection direct, le slot sera directement appelé par le emit de la thread, qui va l'executer.

  5. #5
    Nouveau Candidat au Club
    Inscrit en
    Juin 2008
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Merci pour ces informations

    Effectivement, c'était un assert

    J'ai essayé le QTimer, qui je le pensais, aurait du suffir. C'est parce qu'il ne fonctionnait pas que j'en suis venu à des solutions moins orthodoxes...

    Voilà le code que j'avais écrit à la base pour ma wait dialog:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    WaitDialog::WaitDialog(QWidget* pParent, Qt::WindowFlags pFlag)
    :QDialog(pParent)
    ,mFrame(0)
    {
    	setWindowFlags(pFlag);
    	mUi.setupUi(this);
    	mStartTime.start();
    	QTimer::singleShot(100, this, SLOT(updateInfos()));
    }
     
    void WaitDialog::updateInfos()
    {
    	// Set current pixmap 
    	if
    		(mFrame == mWaitDialogPixmaps->size())
    	{
    		mFrame = 0;
    	}
    	mUi.label->setPixmap((*mWaitDialogPixmaps)[mFrame++]);
     
    	// Set elapsed time.
    	QTime lElapsed(0, 0, 0, 0);
    	lElapsed = lElapsed.addMSecs(mStartTime.elapsed());
    	mUi.mLElapsedTime->setText(lElapsed.toString("HH:mm:ss"));
    	QApplication::processEvents();
    	QTimer::singleShot(100, this, SLOT(updateInfos()));
    }
     
    void VA_WaitDialog::showInstance()	
    {
    	if
    		(!msInstance)
    	{
    		msInstance = new VA_WaitDialog();
    		msInstance->show();
    	}
    }
     
    void VA_WaitDialog::hideInstance()
    {
    	  if
                  (msInstance)
              delete msInstance;
    }
    Celle ci était utilisée dans ma main window de cette manière:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    VA_WaitDialog::showInstance();
    // TRAITEMENT LOURD
    // ...
    void VA_WaitDialog::hideInstance();
    On voyait une fenêtre modale grise figée apparaître sans le défilement des png et du ellapsed time qui disparaissait à la fin du traitement.
    Ca aurait du marcher... Je comprends pas.

    Une idée?

  6. #6
    Nouveau Candidat au Club
    Inscrit en
    Juin 2008
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Les deux premières méthodes appartiennent à VA_WaitDialog
    C'est une erreur de copier coller

  7. #7
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 033
    Points : 13 968
    Points
    13 968
    Par défaut
    C'est grisé car la thread principale effectue ta tache lourd. Elle ne peut donc effectuer autre chose.
    Une methode pas terrible est d'appeler qApp->processEvents () pendant ton gros traitement.

    Et un manière bien meilleur utiliser une thread ce qui t'as voulue faire, mais faut décorélé l'ihm du traitement.

    Comment se déroule l'exécution du traitement?

  8. #8
    Nouveau Candidat au Club
    Inscrit en
    Juin 2008
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    "Une methode pas terrible est d'appeler qApp->processEvents () pendant ton gros traitement."

    Haha, c'est ce que j'ai fini par faire!
    Le traitement, c'est une export PDF/PNG de contenus de widgets. L'utilisateur peut définir la résolution, ça peut donc prendre du temps.
    J'ai mis des qApp->processEvents () entre chaque export de vue... Ca fait illusion

    Une idée toute con que je viens d'avoir serait simplement d'effectuer l'export dans un QThread et de jouer l'animation de la wait dialog dans le GUI thread.

    Mais là j'ai la flem'

    En tout cas merci, ce fut fort instructif!

    Coco

    PS: Chuck Norris peut diviser par zéro

  9. #9
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par vilaincoco Voir le message
    PS: Chuck Norris peut diviser par zéro
    C'est pas comme cela qu'il as été conçue?


  10. #10
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266

Discussions similaires

  1. Utilisation de la fonction wait() de QThread
    Par Invité dans le forum Débuter
    Réponses: 4
    Dernier message: 22/05/2010, 14h05
  2. Waiting a QThread
    Par uriotcea dans le forum Multithreading
    Réponses: 3
    Dernier message: 23/05/2008, 15h34
  3. Pop-up d'une dialog box a partir d'un bouton
    Par bobbyjack dans le forum MFC
    Réponses: 21
    Dernier message: 13/09/2005, 15h32
  4. [awt][dialog]
    Par Ultra-FX dans le forum Agents de placement/Fenêtres
    Réponses: 4
    Dernier message: 06/11/2002, 16h22
  5. Quoi ?! Common Dialog fait crasher DirectDraw ?
    Par Magus (Dave) dans le forum DirectX
    Réponses: 4
    Dernier message: 21/10/2002, 19h01

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