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

PyQt Python Discussion :

Affichage des valeurs d'un compteur [QtGui]


Sujet :

PyQt Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti Avatar de FolDeDol
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Transports

    Informations forums :
    Inscription : Novembre 2013
    Messages : 32
    Par défaut Affichage des valeurs d'un compteur
    Bonjour à vous tous,

    Je débute avec PyQt et je rencontre un problème pour afficher les valeurs issues d'un simple compteur. J'ai créé sous le Qt Designer un QlineEdit et un Bouton.

    En appuyant sur le bouton OK, j'obtiens le résultat 19 dans le QlineEdit alors que je souhaiterais voir 1,2,3,4... défiler un peu à la manière de la console python.

    J'ai essayé d'effacer à chaque incrémentation le QlineEdit et d'ajouter une pause à chaque itération pour afficher la nouvelle valeur mais rien ne se passe.

    Pourriez-vous m'aider à résoudre ce problème ?

    Cordialement,

    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
    import sys
    from ThirdApp import *
     
    class MyForm(QtGui.QDialog) :
        def __init__(self, parent = None) :
            QtGui.QWidget.__init__(self, parent)
            self.ui = Ui_Dialog()
            self.ui.setupUi(self)
            QtCore.QObject.connect(self.ui.OkButton, QtCore.SIGNAL('clicked()'),self.compteur)
     
        def compteur(self):
            a = 1
            while a < 20 :
                self.ui.LineResultat.setText(str(a))
                a = a + 1
     
    if __name__ == "__main__" :
        app = QtGui.QApplication(sys.argv)
        myapp = MyForm()
        myapp.show()
        sys.exit(app.exec_())

  2. #2
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 129
    Par défaut
    Essaie un truc comme ça, pas testé...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    def compteur(self):
        liste = []
        a = 1
        while a < 20 :
            liste.append(a)
            a = a + 1
        st = ','.join(liste)
        self.ui.LineResultat.setText(st)

  3. #3
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Il y a 2 choses à faire:
    - ralentir la boucle, même de peu (5/100 s)
    - forcer l'affichage en demandant l'application des tâches en attente

    Voilà comment (après "from time import sleep"):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        def compteur(self):
            a = 1
            while a < 20 :
                self.lineEdit.setText(str(a))
                sleep(0.05) # <= ralentir la boucle
                QtCore.QCoreApplication.processEvents() #<= forcer l'affichage
                a = a + 1

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 776
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 776
    Par défaut
    Meilleurs vœux tyrtamos et fred1599.

    Tant que le callback (compteur) s’exécute l'affichage ne sera pas mis a jour... .processEvents() resoud le problème pose par le sleep.
    Si l'attente est "petite" ça peut passer... mais dans la pratique, on évite car le GUI se bloque et l'interaction avec l'utilisateur sera problématique.
    note: quand Windows rame, vous ne savez plus trop sur quoi vous avez clique et c'est désagréable...

    Comment faire? Avec Qt tous les QObjects ont un "timer" integre. Il suffit de le demarrer et de mettre a jour compteur et affichage lorsqu'il expire:

    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
    from PyQt4.QtGui import QApplication, QLineEdit
     
    class Counter(QLineEdit):
        _timer_id = None
        def start(self, count=5):
            assert self._timer_id is None
            self._count = count + 1
            self.timerEvent()
            self._timer_id = self.startTimer(500)
     
        def timerEvent(self, event=None):
            self._count -= 1
            self.setText(str(self._count))
            if self._count <= 0:
                self.stop()
     
        def stop(self):
            assert self._timer_id 
            self.killTimer(self._timer_id)        
            self._timer_id = None
     
    if __name__ == '__main__':
        app = QApplication([])
        counter = Counter()
        counter.show()
        counter.start(5)
        app.exec()
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Meilleurs voeux aussi, merci wiztricks!

    Intéressant le timerEvent. Mais il ne concerne que l'affichage du compteur, et pour l'utiliser avec Designer, il faudra créer un "customwidget" du QLineEdit, accompagné de son code plugin: possible, mais pas simple.

    Je rencontre souvent ce problème d'affichage avec du texte, par exemple avec un QTextEdit qui doit afficher des infos au fur et à mesure du déroulement du programme. Si je ne fais rien, il n'affiche que le texte final ce qui n'est ni beau ni intéressant. La seule solution que j'ai trouvée, c'est d'utiliser QtCore.QCoreApplication.processEvents().

    J'ai aussi essayé de récuper le signal "textChanged", afin de n'afficher le texte suivant que quand ce signal a bien été activé par le texte précédent. Mais ça n'évite pas le ".processEvents()".

    Et il faut avoir conscience que si tout le texte (ici la boucle) est émis en 0.01s, même si l'affichage était très très rapide, les yeux humains, eux, ne seraient pas assez! D'où le sleep dans la boucle pour ralentir l'exécution.

    Si tu as une solution pour résoudre ce problème général de façon plus élégante pour l'affichage de textes, je suis très intéressé!

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 776
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 776
    Par défaut
    Salut,
    Citation Envoyé par tyrtamos Voir le message
    Intéressant le timerEvent. Mais il ne concerne que l'affichage du compteur, et pour l'utiliser avec Designer, il faudra créer un "customwidget" du QLineEdit, accompagné de son code plugin: possible, mais pas simple.
    Si le PO prend la peine de comprendre l'exemple d'utilisation avec les timer, il peut aussi l’intégrer dans son code modulo les meme redirections.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class MyForm(QtGui.QDialog) :
        ...
        def timerEvent(self, event=None):
            self._count -= 1
            self.ui.LineResultat.setText(str(self._count))
            if self._count <= 0:
                self.stop()
        ...
    Si tu as une solution pour résoudre ce problème général de façon plus élégante pour l'affichage de textes, je suis très intéressé!
    Le cas général est de s'appliquer a ce que l’exécution d'un callback soit rapide. Les cas particuliers sont quand les traitements effectues dans un callback sont trop longs: il faut alors arbitrer entre des appels a .processEvents() ou la création d'un thread sépare.
    Cela s'applique a tous les GUI classiques Qt, Tk, GTk, Wx,...

    Dans le cas présent, ce n'est la durée des traitements est raisonnable mais on souhaite que les différentes valeurs du décompte s'affichent assez longtemps pour que l'utilisateur voie les mises a jour successives.
    C'est une animation et "assez longtemps" doit être supérieur a une durée de 1/20 - 1/50 de secondes. Si le temps de calcul de la valeur suivante est "petit" vs. cette durée, inutile de créer un thread.

    Ce ne sont pas des "règles" mais des "principes". Ils sont bases sur comment sont construits les GUI et l'ordonnancement coopératif entre callbacks utilisateurs et event-loop.

    Je rencontre souvent ce problème d'affichage avec du texte, par exemple avec un QTextEdit qui doit afficher des infos au fur et à mesure du déroulement du programme.
    Postez un exemple.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre averti Avatar de FolDeDol
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Transports

    Informations forums :
    Inscription : Novembre 2013
    Messages : 32
    Par défaut
    Bonjour à vous,

    Meilleurs voeux pour cette année 2014.
    Je vous remercie pour vos réponses.

    Je ne connaissais pas la notion de QtCore.QCoreApplication.processEvents().

    Je rebondis sur les propos de Tyrtamos :

    Je rencontre souvent ce problème d'affichage avec du texte, par exemple avec un QTextEdit qui doit afficher des infos au fur et à mesure du déroulement du programme. Si je ne fais rien, il n'affiche que le texte final ce qui n'est ni beau ni intéressant. La seule solutihttp://www.developpez.net/forums/images/smilies/icon_redface.gifon que j'ai trouvée, c'est d'utiliser QtCore.QCoreApplication.processEvents()
    Je pense que je vais rencontrer un peu ce type de problème car j'aime bien suivre l'affichage des informations au fur et à mesure du script (je debugge encore au print ).

    Tout comme Tyrtamos, si tu as une solution plus élégante Wiztricks je suis également preneur.

    En tout cas, merci pour votre aide.

    Cordialement,

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Affichage des valeurs disponibles dans une zone de liste déroulante
    Par azerty dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 04/06/2007, 12h29
  2. Pas d'affichage des valeurs nulles avec un COUNT
    Par phoenixz22 dans le forum Langage SQL
    Réponses: 13
    Dernier message: 30/05/2007, 18h39
  3. [SQL] Affichage des valeurs nulles dans un Count
    Par at_first dans le forum Access
    Réponses: 4
    Dernier message: 06/03/2007, 11h07
  4. Réponses: 3
    Dernier message: 05/03/2007, 12h54
  5. Affichage des valeurs des variables avec tkprof
    Par hkhan13 dans le forum Oracle
    Réponses: 2
    Dernier message: 04/07/2006, 11h59

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