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

Python Discussion :

Récupérer les logs de Python pour les afficher dans une IHM (PyQt)


Sujet :

Python

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2015
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2015
    Messages : 77
    Points : 39
    Points
    39
    Par défaut Récupérer les logs de Python pour les afficher dans une IHM (PyQt)
    Bonjour,

    J'aimerais récupérer les logs de Python (tout ce que je vois dans ma console Python) pour ensuite pouvoir l'afficher dans mon IHM.

    J'utilise subprocess.Popen pour exécuter différents traitements. Cela normalement me permet de récupérer les messages d'erreurs etc. avec stdout et stderr.

    Mes traitements ont cette forme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    script = subprocess.Popen(......,shell=False,stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
     
    ui.textErr.setText(script) # afficher les logs dans l'interface
    Ce qui ne marche pas. Qqun peut-il m'aider svp ?

  2. #2
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Salut,

    Citation Envoyé par guy16 Voir le message
    Ce qui ne marche pas.
    En suçant mon pouce, je devine que tu obtiens TypeError: QMachin.setText(QString): argument 1 has type 'tuple'

    communicate() retourne un tuple (info ou données du process, None ou error)

    Donc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if script[1] is not None:
        ui.textErr.setText(script[1])

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2015
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2015
    Messages : 77
    Points : 39
    Points
    39
    Par défaut
    J'obtiens cette erreur : TypeError: QTextEdit.setText(str): argument 1 has unexpected type 'bytes'

    Mon code est le même, j'ai rajouté ta partie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
                script = subprocess.Popen(.........., shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
     
                if script[1] is not None:
                    ui.textEdit.setText(script[1])

  4. #4
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Ben, essaye comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        ui.textEdit.setText(str(script[1]))
    Dans le pire des cas fais un print(script) pour voir ce que c'est exactement.

    Edit: modifié pour Python 3

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2015
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2015
    Messages : 77
    Points : 39
    Points
    39
    Par défaut
    Ah oui, merci!
    Ça marche, mais, ça ne m'affiche pas les messages en temps réel, ça me l'affiche une fois le process terminé. Est-ce possible de l'avoir en temps réel ?
    Et il ne m'affiche plus rien dans la console Python maintenant (ce qui n'est pas grave-grave mais j'aimerais bien l'avoir quand même).
    Et j'ai l'impression qu'il ne m'affiche pas tout ce que j'avais dans la console Python. Est-ce possible d'avoir aussi les print affiché dans l'interface par exemple ?

    Désolé ça fait beaucoup de choses..

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

    Citation Envoyé par guy16 Voir le message
    Ça marche, mais, ça ne m'affiche pas les messages en temps réel, ça me l'affiche une fois le process terminé. Est-ce possible de l'avoir en temps réel ?
    Si vous programmez avec Qt, il sera préférable d'utiliser QProcess à la place du module subprocess, car vous aurez toute la glue pour communiquer entre le QProcess et le GUI (il vous faudrait la ré-écrire sinon).

    Exemple déterré d'un vieux post:
    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
    import collections
    from PyQt4.QtCore import QProcess, pyqtSignal, pyqtSlot
     
    class Process(QProcess):
        read_line = pyqtSignal(str)
     
        def __init__(self):
            super().__init__()
            self._queue = collections.deque()
            self.readyReadStandardOutput.connect(self._has_data)
            self.finished[int].connect(self._start_next)
     
        @pyqtSlot()    
        def _has_data(self):
            data = self.readAllStandardOutput()
            for line in  bytes(data).decode('utf-8').splitlines():
                if line:
                    self.read_line.emit(line)
     
        def start(self, command):
            queue = self._queue
            if not queue:
                self.read_line.emit('start: %s' % command)
                super().start(command)
            queue.append(command)
     
        @pyqtSlot(int)
        def _start_next(self, exit_code):
            queue = self._queue
            queue.pop()
            self.read_line.emit('*done*')
            if queue:
                self.read_line.emit('start: %s' % queue[0])
                super().start(queue[0])
     
    if __name__ == '__main__':
        import sys
        from PyQt4.QtGui import QApplication, QTextEdit
     
        app = QApplication(sys.argv)
        display = QTextEdit()
        display.show()
     
        process = Process()
        process.read_line.connect(display.append)
     
        process.start('python3 test.py"')
     
        app.exec_()
    Si on y colle le "test.py":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #! /usr/bin/env python3
    #! -*- coding:utf-8 -*-
    import time
    import sys
     
    for x in range(20):
        print ('count:', x)
        sys.stdout.flush()
        time.sleep(0.1)
    Remarquez le "sys.stdout.flush()" et mettez le en commentaires "pour voir".
    Ca raconte que les opérations d'écriture sur un pipe sont "buffered": çà n'écrit pas les lignes au fur et à mesure des "print" mais çà attend d'avoir un certain nombre de bytes dans un buffer interne avant de...
    => changer cela est plutôt "tricky".

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

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2015
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2015
    Messages : 77
    Points : 39
    Points
    39
    Par défaut
    Oui j'utilise Qt (PyQt5 et Python 3.4).

    Arf.. ça va être compliqué de ré-écrire tout mon code pour utiliser QProcess... (manque de temps surtout)
    et la structure de mon code/GUI est un peu particulière et je sens que je vais avoir du mal à la ré-écrire en utilisant QProcess..
    Est-ce vraiment difficile de pouvoir faire ce que je voudrais avec subprocess ?

  8. #8
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Tu peux utiliser cette méthode:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    script = subprocess.Popen(.........., shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
    while 1:
        text = reply.stdout.readline()
        if type(text) != str or text == '' and reply.poll() != None: 
            break
        print(text)
    Il faudra que tu analyses le texte pour différentier les données des erreurs.

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2015
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2015
    Messages : 77
    Points : 39
    Points
    39
    Par défaut
    Voici l'erreur que ça me sort :

    text = script.stdout.readline()
    AttributeError: 'tuple' object has no attribute 'stdout'


    Je peux accéder à stdout.readline() que si je n'ai pas communicate à la fin du subprocess mais j'obtiens un text ==' ', je n'ai aucun retour.

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2015
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2015
    Messages : 77
    Points : 39
    Points
    39
    Par défaut
    Voici l'erreur que ça me sort :

    text = script.stdout.readline()
    AttributeError: 'tuple' object has no attribute 'stdout'


    Je peux accéder à stdout.readline() que si je n'ai pas communicate à la fin du subprocess mais j'obtiens un text ==' ', je n'ai aucun retour.

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par guy16 Voir le message
    Arf.. ça va être compliqué de ré-écrire tout mon code pour utiliser QProcess... (manque de temps surtout)
    et la structure de mon code/GUI est un peu particulière et je sens que je vais avoir du mal à la ré-écrire en utilisant QProcess..
    Est-ce vraiment difficile de pouvoir faire ce que je voudrais avec subprocess ?
    Si vous ne voulez pas que le GUI soit bloqué en attendant la fin du subprocess et afficher le log au fur et à mesure, il va falloir permettre un déroulement asynchrone et organiser la communication entre les deux.
    Soit vous utilisez QProcess qui a déjà tout ce qu'il faut pour réaliser cela simplement, soit vous essayez de comprendre le problème pour trouver comment réaliser cela "simplement" avec subprocess.
    Et les engins prêts à l'emploi tels que QProcess sont faits pour ceux qui ne veulent/peuvent pas se prendre le chou...
    Après vous pouviez revoir vos ambitions à la baisse et bloquer le GUI pendant que... pour tout afficher à la fin.

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

  12. #12
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2015
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2015
    Messages : 77
    Points : 39
    Points
    39
    Par défaut
    J'ai essayé il y a qq mois de faire fonctionner un throbber avec un QProcess sans réussir.
    Je ne suis pas dev à la base donc faire des déroulements asynchrones ne sont pas des choses que je maîtrise, ni ne comprend totalement

    Après vous pouviez revoir vos ambitions à la baisse et bloquer le GUI pendant que... pour tout afficher à la fin.
    Oui cela m'irait, mais j'aimerais bien avoir tout ce qui apparaît dans ma console Python, apparaître dans mon GUI. Ce que je n'arrive pas à faire pour l'instant.

  13. #13
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par guy16 Voir le message
    Oui cela m'irait, mais j'aimerais bien avoir tout ce qui apparaît dans ma console Python, apparaître dans mon GUI. Ce que je n'arrive pas à faire pour l'instant.
    ben, alors:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    data = subprocess.check_output("<<la commande>>")
    ui.textEdit.append(data.decode())
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  14. #14
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2015
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2015
    Messages : 77
    Points : 39
    Points
    39
    Par défaut
    Ah merci !
    Je n'avais pas utilisé check_output car dans la doc il y a écrit Note Do not use stdout=PIPE or stderr=PIPE with this function. The child process will block if it generates enough output to a pipe to fill up the OS pipe buffer as the pipes are not being read from. mais je ne connaissais pas decode()

    Bref, merci

  15. #15
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par guy16 Voir le message
    Je n'avais pas utilisé check_output car dans la doc il y a écrit Note Do not use stdout=PIPE or stderr=PIPE with this function. The child process will block if it generates enough output to a pipe to fill up the OS pipe buffer as the pipes are not being read from. mais je ne connaissais pas decode()
    La documentation dit cela pour "check_call", pas pour check_output.
    Pour le .decode, c'est une plus longue histoire...
    Prenez une séquence de "bytes" (comme ce qui est retourné dans le PIPE du subprocess):
    Si vous vous contentez d'appliquer "str" à cette chose là, çà donne:
    Autrement dit une chaîne de caractère qui contient bien plus que "abc" car construite à partir de s.__str__().
    On devrait écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> str(s, "utf-8")
    'abc'
    >>>
    J'y préfère s.decode()

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

  16. #16
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2015
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2015
    Messages : 77
    Points : 39
    Points
    39
    Par défaut
    Ok, merci pour l'explication de decode() !

    La documentation dit cela pour "check_call", pas pour check_output.
    Il me semble que c'est pour check_output aussi : https://docs.python.org/3.4/library/...s.check_output (l'encadré en grisé)

  17. #17
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Citation Envoyé par guy16 Voir le message
    Voici l'erreur que ça me sort :

    text = script.stdout.readline()
    AttributeError: 'tuple' object has no attribute 'stdout'

    J'ai oublié de supprimer communicate() de ta ligne de code.

Discussions similaires

  1. Réponses: 7
    Dernier message: 23/09/2009, 10h02
  2. Réponses: 0
    Dernier message: 21/09/2009, 23h41
  3. Réponses: 62
    Dernier message: 16/04/2009, 10h09
  4. [Toutes versions] Extraire une valeur d'une ListBox pour l'afficher dans une cellule
    Par stid59 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 06/04/2009, 22h05
  5. récupérer le nom du serveur et l'afficher dans une jsp
    Par barouz dans le forum Servlets/JSP
    Réponses: 21
    Dernier message: 19/04/2007, 15h32

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