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 :

Utilisation des objets du user interface dans la vue python Qt5 MVC


Sujet :

PyQt Python

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 7
    Points : 6
    Points
    6
    Par défaut Utilisation des objets du user interface dans la vue python Qt5 MVC
    Bonjour a tous,
    Je souhaite afficher les résultats générés par un solveur dans textBrowser Qt5 à l'aide de la méthode append. J'arrive déjà à récupérer la valeur dans une variable et l'afficher à partir d'un print(value) mais quand je fait textBrowser.append(value) je n'ai pas de résultat.

    voici le code qui implémente ma vue.

    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
     
    from PyQt5.QtWidgets import QMainWindow
    from PyQt5.QtCore import pyqtSlot
    from Views.mainwindow import Ui_MainWindow
     
    class MainWiew(QMainWindow):
     
        def __init__(self,model,controller):
            super().__init__()
            self._model = model
            self._controller = controller
            self._ui = Ui_MainWindow()
            self._ui.setupUi(self)
     
            #connection of widgets to controller
            self._ui.pushButton_3.clicked.connect(self._controller.browserSlot)
            self._ui.pushButton_5.clicked.connect(self._controller.runSlot)
            self._ui.pushButton_4.clicked.connect(self._controller.exportSlot)
            self._ui.pushButton_6.clicked.connect(self._controller.stopSlot)
            self._ui.pushButton.clicked.connect(self._controller.modifySlot)
            self._ui.pushButton_2.clicked.connect(self._controller.addSlot)
     
            # connection of result to receive_signal method
            self._model.mySignal.connect(self.receive_signal)
     
     
        @pyqtSlot(str)
        def receive_signal(self,value):
            self._ui.textBrowser.append(value) #no display here
            print(value) #able to dispay
    J'ai également essayé d'appeler la méthode receive_signal dans l'initialisation. elle ne m'affiche que le premier résultat et ensuite ... plus rien
    En cas de besoin voici le code de mon model :
    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
     
    from PyQt5.QtCore import QObject, pyqtSignal
     
    class Model(QObject):
        mySignal = pyqtSignal( str )
     
     
        def __init__(self):
            super().__init__()
            self.prog_base = ''
            self.data = ''
            self.constraints = ''
            self.newVal = ''
            self._list_patterns = []
            QObject.__init__(self)
     
        #def refresh(self):
     
        def mod(self ,m="none"):
            if str(m) not in self._list_patterns:
                self._list_patterns.append(m)
                self.mySignal.emit(str(m))

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

    Il me semble que QTextBrowser est "readOnly" par défaut.

    Mais je suggère de vérifier que cette classe est bien celle qui faut. En effet, QTextBrowser hérite de QTextEdit qui supporte aussi le "richtext" (sous-ensemble de html). Il a seulement l'avantage de supporter les liens hypertexte, ce que ne fait pas QTextEdit.
    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

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    Merci Tyrtamos pour ta réponse,

    Effectivement il est en mode "readOny" par défaut.

    Je l'ai donc mis à False avec la méthode setReadOnly() mais pas d'amélioration, le seul changement est que je peux maintenant entrer des informations à partir du clavier.
    J'ai également essayé avec QTextEdit j'ai toujours pas d'affichage.

    Mais chose bizarre quand j'affiche un texte banal dans la méthode __init__ il s'affiche bien (aussi bien avec QTextEdit qu'avec QTextbrowser), mais jamais de façon automatique dans ma méthode "receive_signal".

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

    Par curiosité, j'ai fait un code de test. J'utilise habituellement les QTextBrowser pour afficher un texte html que je crée avec BlueGriffon (éditeur html gratuit). Attention tout de même: QTextBrowser et QTextEdit ne supportent qu'un sous-ensemble de html, que Qt appelle "RichText". Je paramètre si nécessaire le texte html avec .format(...). Et je l'affiche dans le QTextBrowser avec .setHtml(...). Comme je l'ai dit, l'avantage de QTextBrowser est qu'il supporte les liens hypertexte (contrairement au QTextEdit).

    Pour simuler ton "receive_signal", j'ai mis un bouton qui, lorsqu'on le clique, doit ajouter un texte à la page. Et... ça marche, à ma grande surprise!

    ???

    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/python3
    # -*- coding: utf-8 -*-
     
    import sys
    from PyQt5 import QtCore, QtGui, QtWidgets
     
    #############################################################################
    class Fenetre(QtWidgets.QMainWindow):
     
        #========================================================================
        def __init__(self, parent=None):
            super().__init__(parent)
     
            self.resize(800, 600)
            self.setWindowTitle("Test QTextBrowser")
     
            # crée le widget d'affichage d'un richtext
            self.rtexte = QtWidgets.QTextBrowser(self)
            self.rtexte.setReadOnly(False)
     
            # crée un bouton
            self.bouton = QtWidgets.QPushButton("Ajout d'un texte", self)
            self.bouton.clicked.connect(self.ajout)
     
            html = """<!DOCTYPE html>
    <html>
      <head>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        <title></title>
      </head>
      <body>
        <h3><span style="font-family: Helvetica,Arial,sans-serif" ;=""><b>Test de
              QTextBrowser</b></span></h3>
        <p><i>Avec le bonjour de Tyrtamos!</i></p>
      </body>
    </html>
                """
     
            # affiche le texte html
            self.rtexte.setHtml(html)
     
            # place le QTextBrowser dans la fenêtre
            self.setCentralWidget(QtWidgets.QFrame())
            posit = QtWidgets.QGridLayout()
            posit.addWidget(self.rtexte, 0, 0)
            posit.addWidget(self.bouton, 1, 0)
            self.centralWidget().setLayout(posit)
     
        #========================================================================
        def ajout(self, checked=False):
            self.rtexte.append("toto")
            self.rtexte.append("tata")
            self.rtexte.append("titi")
     
    #############################################################################
    if __name__ == '__main__':
        app = QtWidgets.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

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    Bonjour,
    C'est là mon problème : Je ne dois pas utiliser de bouton pour afficher dans le QTextBrowser.
    Dès que j’exécute le programme le solveur peut passer souvent plus de 5 minutes avant trouver un seul résultat alors qu'il est sensé fournir à terme une centaine de résultats (ce qui demande beaucoup de temps) et je ne sais pas à priori à quel moment il y aura un résultat.
    Pour ne pas faire attendre l'utilisateur pendant un temps indéfini il doit afficher un résultat dès que possible en attendant le prochain résultat.
    du coup j'ai pensé à faire une sorte de "souscription" à la méthode qui m'envoie le résultat depuis le modèle :

    Dans ma vue je fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     self._model.mySignal.connect(self.receive_signal)
    Dans mon model je fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     mySignal = pyqtSignal( str )
     
        def mod(self ,m="none"): #La variable "m" reçois un résultat d'une résolution envoyé par le solveur
                self.mySignal.emit(str(m)) #j'envoie "m" dans ma vue pour affichage

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

    J'ai modifié autant que j'ai pu mon code de test pour se rapprocher de ton cas, et je ne trouve toujours pas de problème.

    Dans ce code, le clic sur le bouton lance la méthode "simulsolveur" qui, elle-même, émet le signal "mySignal", ce qui lance la méthode "ajout".

    Lance cet exemple sur ton PC et vérifie que ça marche aussi chez toi. Si ok, fais la comparaison avec ton code.

    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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
     
    import sys
    from PyQt5 import QtCore, QtGui, QtWidgets
     
    #############################################################################
    class Fenetre(QtWidgets.QMainWindow):
     
        mySignal = QtCore.pyqtSignal(str)
     
        #========================================================================
        def __init__(self, parent=None):
            super().__init__(parent)
     
            self.resize(800, 600)
            self.setWindowTitle("Test QTextBrowser")
     
            # la réception de mySignal lancera la méthode ajout
            self.mySignal.connect(self.ajout)
     
            # crée le widget d'affichage d'un richtext
            self.rtexte = QtWidgets.QTextBrowser(self)
            self.rtexte.setReadOnly(False)
     
            # crée un bouton
            self.bouton = QtWidgets.QPushButton("Ajout d'un texte", self)
            self.bouton.clicked.connect(self.simulsolveur)
     
            html = """<!DOCTYPE html>
    <html>
      <head>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        <title></title>
      </head>
      <body>
        <h3><span style="font-family: Helvetica,Arial,sans-serif" ;=""><b>Test de
              QTextBrowser</b></span></h3>
        <p><i>Avec le bonjour de Tyrtamos!</i></p>
      </body>
    </html>
                """
     
            # affiche le texte html
            self.rtexte.setHtml(html)
     
            # place le QTextBrowser dans la fenêtre
            self.setCentralWidget(QtWidgets.QFrame())
            posit = QtWidgets.QGridLayout()
            posit.addWidget(self.rtexte, 0, 0)
            posit.addWidget(self.bouton, 1, 0)
            self.centralWidget().setLayout(posit)
     
        #========================================================================
        def simulsolveur(self, checked=False):
            """méthode lancée par un clic sur le bouton
            """
            self.mySignal.emit("toto") #émet le signal "mySignal" avec la valeur
            self.mySignal.emit("tata") #émet le signal "mySignal" avec la valeur
            self.mySignal.emit("titi") #émet le signal "mySignal" avec la valeur
     
        #========================================================================
        def ajout(self, valeur):
            """méthode lancée par la réception d'un signal "mySignal"
            """
            self.rtexte.append(valeur)
     
    #############################################################################
    if __name__ == '__main__':
        app = QtWidgets.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

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par tyrtamos Voir le message

    Lance cet exemple sur ton PC et vérifie que ça marche aussi chez toi. Si ok, fais la comparaison avec ton code.
    Bonjour,
    J'ai exécuté ton code il fonctionne bien alors j'ai essayer de le rapprocher "encore plus" de mon problème en ajoutant un temps d'attente cette fois-ci comme dans mon programme.
    Je me suis rendu compte que le "richText" tout comme mon "QTextBrowser" affiche ce que je demande mais après un cumul de tous les temps d'attente alors qu'avec le print il affiche le résultat dès qu'il est disponible.
    Et comme j’attendais pas tout le temps d’exécution donc je ne m'en rendait pas compte
    Voici ton code modifié pour mieux comprendre ce que j'explique :
    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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
     
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
     
    import sys
    import time
    from PyQt5 import QtCore, QtGui, QtWidgets
     
    #############################################################################
    class Fenetre(QtWidgets.QMainWindow):
     
        mySignal = QtCore.pyqtSignal(str)
     
        #========================================================================
        def __init__(self, parent=None):
            super().__init__(parent)
     
            self.resize(800, 600)
            self.setWindowTitle("Test QTextBrowser")
     
            # la réception de mySignal lancera la méthode ajout
            self.mySignal.connect(self.ajout)
     
            # crée le widget d'affichage d'un richtext
            self.rtexte = QtWidgets.QTextBrowser(self)
            self.rtexte.setReadOnly(False)
     
            # crée un bouton
            self.bouton = QtWidgets.QPushButton("Ajout d'un texte", self)
            self.bouton.clicked.connect(self.simulsolveur)
     
            html = """<!DOCTYPE html>
    <html>
      <head>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        <title></title>
      </head>
      <body>
        <h3><span style="font-family: Helvetica,Arial,sans-serif" ;=""><b>Test de
              QTextBrowser</b></span></h3>
        <p><i>Avec le bonjour de Tyrtamos!</i></p>
      </body>
    </html>
                """
     
            # affiche le texte html
            self.rtexte.setHtml(html)
     
            # place le QTextBrowser dans la fenêtre
            self.setCentralWidget(QtWidgets.QFrame())
            posit = QtWidgets.QGridLayout()
            posit.addWidget(self.rtexte, 0, 0)
            posit.addWidget(self.bouton, 1, 0)
            self.centralWidget().setLayout(posit)
     
     
        #========================================================================
        def simulsolveur(self, checked=False):
            """méthode lancée par un clic sur le bouton
            """
     
            self.mySignal.emit("toto") #émet le signal "mySignal" avec la valeur
            time.sleep(1)
            self.mySignal.emit("tata") #émet le signal "mySignal" avec la valeur
            time.sleep(5)
            self.mySignal.emit("titi") #émet le signal "mySignal" avec la valeur
            time.sleep(8)
            self.mySignal.emit("tutu") #émet le signal "mySignal" avec la valeur
     
        #========================================================================
        def ajout(self, valeur):
            """méthode lancée par la réception d'un signal "mySignal"
            """
            self.rtexte.append(valeur)
            print(valeur)
     
    #############################################################################
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
        fen = Fenetre()
        fen.show()
        sys.exit(app.exec_())
    Es ce qu'il existe une manière d'afficher mes valeurs au fur et à mesure sans avoir à attendre tout le temps ?

  8. #8
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    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 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Ajoute une simple ligne à ta méthode d'affichage:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        def ajout(self, valeur):
            """méthode lancée par la réception d'un signal "mySignal"
            """
            self.rtexte.append(valeur)
            QtCore.QCoreApplication.processEvents() 
            print(valeur)
    Ça devrait forcer l'affichage en temps réel. Le principe est simple: le graphique fonctionne par évènements. Une fois lancé et affiché, il attend qu'un évènement arrive (clavier, souris, action utilisateur, réseau, affichage, etc...) et le met dans une pile d'attente. Dès qu'il le peut, il traite les évènements de la pile. La ligne ajoutée ici force le traitement des évènements en attente, et donc ici l'affichage demandé.
    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

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    Ah ça fonctionne parfaitement comme je souhaitais

    Citation Envoyé par tyrtamos Voir le message
    Ajoute une simple ligne à ta méthode d'affichage:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
            QtCore.QCoreApplication.processEvents()
    Ça devrait forcer l'affichage en temps réel.
    C'est donc cette ligne qui manquait à mon programme. Merciiii
    sujet résolu !!!

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 04/02/2011, 20h08
  2. Réponses: 3
    Dernier message: 24/02/2007, 00h04
  3. Utiliser des objets automation dans Oracle
    Par WebPac dans le forum Forms
    Réponses: 10
    Dernier message: 29/11/2006, 19h17
  4. Utiliser des objets SWING dans une vue RCP
    Par manuga72 dans le forum Eclipse Platform
    Réponses: 1
    Dernier message: 20/10/2006, 17h26

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