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

  1. #1
    Membre du Club 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
    Points : 53
    Points
    53
    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 éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 808
    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 : 3 808
    Points : 7 086
    Points
    7 086
    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)
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  3. #3
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    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 461
    Points : 9 248
    Points
    9 248
    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
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 277
    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 277
    Points : 36 762
    Points
    36 762
    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 éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    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 461
    Points : 9 248
    Points
    9 248
    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é!
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 277
    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 277
    Points : 36 762
    Points
    36 762
    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 du Club 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
    Points : 53
    Points
    53
    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,

  8. #8
    Membre du Club 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
    Points : 53
    Points
    53
    Par défaut
    @ wiztricks : nos messages se sont croisés. Je vais essayer de comprendre ton dernier mail sur les timer et de poster un exemple rapidement.

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 277
    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 277
    Points : 36 762
    Points
    36 762
    Par défaut
    Citation Envoyé par FolDeDol Voir le message
    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 ).
    "print" envoie ses données sur stdout, pas dans un widget.
    Le module logging permet de remplacer avantageusement les "print". Bien utilise, il permet de supprimer les messages de DEBUG sans editer le code (et supprimer le "print").
    Si j'ai du temps je posterai un logging handler qui affiche dans un TextEdit.
    note: pour rediriger les print dans un TextEdit, on peut s'inspirer de la discussion
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  10. #10
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    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 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Citation Envoyé par wiztricks Voir le message
    Postez un exemple
    Dans certains de mes programmes, j'utilise un QTextEdit pour afficher des infos au fur et à mesure de son exécution. Par exemple, un programme de sauvegarde "miroir" va afficher les copies faites et les fichiers effacés. On peut aussi afficher les résultats d'un calcul ou d'une requête ou encore des messages d'erreur. Si on y ajoute des fonctions copier-coller, glisser-déposer, imprimer, éditer_pdf, effacer, etc..., c'est vraiment très pratique. En plus, pour des tâches longues, l'affichage progressif indique à l'utilisateur que le programme est bien en train de travailler.

    Voilà un petit exemple qui montre le problème d'affichage. La fenêtre ne contient que 2 widgets: un bouton pour lancer l'affichage et un QTextEdit pour afficher. Une fois le bouton cliqué, on affiche 1000 lignes créés au hasard.

    La différence se fait ici dans la méthode affiche:
    - si je commente la ligne "QtCore.QCoreApplication.processEvents()", les 1000 lignes sont affichées d'un seul coup à la fin de l'exécution
    - si je décommente cette ligne, j'ai bien l'affichage progressif des 1000 lignes, et c'est l'effet voulu.

    Pour le moment, la solution avec ".processEvents()" fonctionne assez bien, mais peut-être y en a-t-il une autre qui fonctionne encore mieux?

    Voilà le code (Python 2.7, PyQt4):

    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    from __future__ import division
     
    import sys
    from PyQt4 import QtCore, QtGui
     
    #############################################################################
    # création d'une chaine de caractères au hasard
    from random import randint
     
    cars = u" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    lgcars = len(cars)
     
    def creachaine():
        # longueur du texte au hasard
        lg = randint(0, 255)
        # texte au hasard
        return ''.join([cars[randint(0, lgcars-1)] for i in xrange(0, lg)])
     
    #############################################################################
    class Fenetre(QtGui.QWidget):
     
        def __init__(self, parent=None):
            super(Fenetre, self).__init__(parent)
     
            self.resize(800, 600)
     
            self.bouton = QtGui.QPushButton(u"Affichez!", self)
            self.bouton.clicked.connect(self.lanceAffiche) 
     
            self.edit = QtGui.QTextEdit(self)
     
            posit = QtGui.QGridLayout()
            posit.addWidget(self.bouton, 0, 0)
            posit.addWidget(self.edit, 1, 0)
            self.setLayout(posit)
     
        def lanceAffiche(self):
            """lance l'affichage du texte"""
            for i in xrange(0, 1000):
                ligne = creachaine() # création d'une chaine au hasard
                self.affiche(u"%4d: %s" % (i+1, ligne))
     
        def affiche(self, msg):
            """Ecrire dans le widget edit (QTextEdit)"""
            # ajoute msg au texte existant
            self.edit.append(msg)
            # fait bouger le curseur à la fin du texte
            self.edit.moveCursor(QtGui.QTextCursor.End, 
                                                     QtGui.QTextCursor.MoveAnchor)
            # force le rafraichissement pour affichage en temps réel
            QtCore.QCoreApplication.processEvents() 
     
    #############################################################################
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        fen = Fenetre()
        fen.show()
        sys.exit(app.exec_())
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 277
    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 277
    Points : 36 762
    Points
    36 762
    Par défaut
    Salut Tyrtamos,

    Le soucis pose dans le post initial relève de "l'animation". Enfin c'est ce que je comprends lorsque le PO dit:
    Citation Envoyé par FolDeDol Voir le message
    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.
    De plus, est utilise un QlineEdit dont le contenu est remplace par la nouvelle valeur du compteur. Si on souhaite que l'utilisateur "voie" cette valeur, il faut l'afficher un certain temps.
    Utiliser sleep et .processEvent "fonctionnent" mais "limiter la durée des callbacks" rend préférable l'utilisation d'un timer.

    Si je lis les cas d'utilisation présentés:
    Dans certains de mes programmes, j'utilise un QTextEdit pour afficher des infos au fur et à mesure de son exécution. Par exemple, un programme de sauvegarde "miroir" va afficher les copies faites et les fichiers effacés. On peut aussi afficher les résultats d'un calcul ou d'une requête ou encore des messages d'erreur. Si on y ajoute des fonctions copier-coller, glisser-déposer, imprimer, éditer_pdf, effacer, etc..., c'est vraiment très pratique. En plus, pour des tâches longues, l'affichage progressif indique à l'utilisateur que le programme est bien en train de travailler.
    Nous avons un widget "Display" qui affiche une sorte de journal de ce qui est expédie par différents traitements et autant de callbacks.
    Si un des callbacks expédie 1000 lignes, appeler .processEvents pour rafraîchir Display histoire de montrer que ça avance fait sens.
    De même qu'il fera sens de pousser certains traitements dans des threads sépares et poster des messages montrant la progression.

    En simplifiant un peu votre code, ca donne:
    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
    from PyQt4.QtCore import QCoreApplication
    from PyQt4.QtGui import QTextCursor, QTextEdit, QApplication, QWidget, QVBoxLayout, QPushButton
     
    class Display(QTextEdit):
        pass
     
    def long_callback(display, count=1000):
        app = QCoreApplication.instance()
     
        for x in range(count):
            display.append('line-%d' % x)
            app.processEvents()
     
    if __name__ == '__main__':
        app = QApplication([])
     
        widget = QWidget()
        widget.resize(800, 600)
     
        display = Display(widget)
     
        b1 = QPushButton(u'long', widget)
        b1.clicked.connect(lambda: long_callback(display))
     
        layout = QVBoxLayout()
        layout.addWidget(b1)      
        layout.addWidget(display)
        widget.setLayout(layout)
     
        widget.show()
     
        app.exec()
    L'essentiel se passe ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Display(QTextEdit):
        pass
     
    def long_callback(display, count=1000):
        app = QCoreApplication.instance()
     
        for x in range(count):
            display.append('line-%d' % x)
            app.processEvents()
    notez que l'appel a .processEvents() est de la responsabilité du callback qui "invoque" append: c'est lui qui bloque les mises a jour.

    Si on essaie de coller un peu plus a vos cas d'utilisations, on va avoir nombre de callbacks qui feront quelques append. Simuler cela complique un peu le code mais, dans ce cas, inutile d'appeler .processEvents : on espere rendre la main a l'event-loop assez souvent.
    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    from PyQt4.QtCore import QCoreApplication, QObject
    from PyQt4.QtGui import QTextCursor, QTextEdit, QApplication, QWidget, QVBoxLayout, QPushButton
     
     
    class Display(QTextEdit):
        pass
     
     
    class TimedCB(QObject):
        _timer_id = None
        _delay = 5
     
        def __init__(self, parent=None, display=None, count=1000):
            super().__init__(parent)
            self._display = display
            self._count = count
     
        def start(self):
            assert self._timer_id is None
            self._timer_id = self.startTimer(self._delay)  
            self._left = 0
     
        def timerEvent(self, event=None):
            z = random.randint(1, 5)
            for _ in range(z):
                display.append('z= %d, line-%d' % (z, self._left)) 
                self._left += 1
     
            if self._left > self._count:
                self.killTimer(self._timer_id)
                self._timer_id = None
     
    if __name__ == '__main__':
        app = QApplication([])
     
        widget = QWidget()
        widget.resize(800, 600)
     
        display = Display(widget)
     
        b2 = QPushButton(u'timed callbacks', widget)
        timed_cb = TimedCB(parent=widget, display=display)
        b2.clicked.connect(timed_cb.start)
     
        layout = QVBoxLayout()
        layout.addWidget(b2)      
        layout.addWidget(display)
        widget.setLayout(layout)
     
        widget.show()
     
        app.exec()

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

  12. #12
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    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 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour wiztricks,

    Merci pour cette solution!

    L'utilisation du timer est intéressante, mais j'ai bien peur qu'elle ne convienne pas à mon application. En effet, c'est l'application qui fabrique les lignes à afficher pendant son déroulement, et ces lignes doivent parvenir à l'affichage au fur et à mesure. Par ailleurs, l'affichage ne peut pas ralentir l'application: j'accepte même que plusieurs lignes soient affichées en même temps si l'affichage est moins rapide que le traitement.

    La seule chose que je veux éviter, c'est que toutes les lignes attendent la fin du traitement pour être affichées alors que l'utilisateur attend devant un écran muet. C'est ce qui se passe dans mon exemple lorsque je n'utilise pas .processEvents().

    Pour revenir à ta solution, je ne peux pas attendre que toutes les lignes aient été créées pour les faire afficher une à une au rythme du timer alors que le traitement est déjà terminé.

    La solution du .processEvents() est beaucoup plus simple et correspond mieux à mon problème. Mais: cette solution a-t-elle vraiment des inconvénients?
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  13. #13
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 277
    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 277
    Points : 36 762
    Points
    36 762
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    La solution du .processEvents() est beaucoup plus simple et correspond mieux à mon problème. Mais: cette solution a-t-elle vraiment des inconvénients?
    Il y a plusieurs solutions pour mettre a jour l'affichage depuis un callback qui fera des traitements longs - et .sleep n'est pas un traitement "long".

    .processEvents est une de ces solutions.
    Elle a 2 inconvénients.
    La durée de traitement et réactivité du GUI vont dépendre l'un de l'autre. Vous souhaitiez "Par ailleurs, l'affichage ne peut pas ralentir l'application:", c'est râpé.

    Si le traitement est plus complique qu'un appel de fonction sans paramètres, il faudra pouvoir "tester" son comportement sur des plages significatives "hors GUI" - tester avec des singes est une technique répandue mais peu recommandable -.
    Le traitement pourra afficher des messages pour indiquer sa progression (le module logging est fait pour ça).

    Est-ce qu'on intégrera le traitement dans la thread du GUI (et des appels a .processEvents si on veut loguer dans un textEdit) ou est-ce qu'il tournera dans son propre thread?

    Chacun devra choisir la solution adaptée a un contexte particulier...
    Si vous programmez avec Qt, l'article du wiki montre les différentes possibilités a appliquer suivant le type de traitement.

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

  14. #14
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    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 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Merci wiztricks!

    Et merci aussi pour le lien très intéressant du wiki Qt.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

+ 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