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 :

Pyqt et threading - Non affichaqe d’un widget


Sujet :

PyQt Python

  1. #1
    Membre expérimenté

    Profil pro
    Enseignant
    Inscrit en
    Juillet 2003
    Messages
    296
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juillet 2003
    Messages : 296
    Par défaut Pyqt et threading - Non affichaqe d’un widget
    Bonjour,
    Je fais une mini application avec PyQt pour illustrer le threading et les sockets. Mon backend fonctionne mais je me retrouve confronté à un problème…
    J’ai un QScrollArea dans lequel, en fonction des messages tapés soit dans un QLineEdit, soit reçu via un thread qui simule la réception d’un message, je crée un QLabel avec le message et une couleur.

    Quand je tape un texte dans le QLineEdit, mes QLabels sont affichés dans le scrollArea. Par contre, les messages envoyés par le thread ne sont tout simplement pas affichés ! Pourtant, je suis certain que le label est créé…

    Pouvez-vous m’aider à trouver le comment du pourquoi ?

    Merci,
    Fichiers attachés Fichiers attachés

  2. #2
    Expert confirmé

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Salut,

    Le message signale que le thread essaye d'accéder à une classe qui est en dehors de sa portée.

    Les signaux de Qt sont là pour résoudre cela.
    Ton code modifié:
    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
     
    import sys
    from threading import Thread
    from time import sleep
     
    from PyQt5 import QtCore, QtWidgets
    from PyQt5.QtCore import pyqtSignal, pyqtSlot
    from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QLabel
     
     
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setObjectName("MainWindow")
            MainWindow.resize(445, 333)
            self.centralwidget = QtWidgets.QWidget(MainWindow)
            self.centralwidget.setObjectName("centralwidget")
            self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralwidget)
            self.verticalLayout_2.setObjectName("verticalLayout_2")
            self.verticalLayout = QtWidgets.QVBoxLayout()
            self.verticalLayout.setObjectName("verticalLayout")
            self.scrollArea = QtWidgets.QScrollArea(self.centralwidget)
            self.scrollArea.setWidgetResizable(False)
            self.scrollArea.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)
            self.scrollArea.setObjectName("scrollArea")
            self.scrollAreaWidgetContents = QtWidgets.QWidget()
            self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 423, 256))
            self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
            self.scrollArea.setWidget(self.scrollAreaWidgetContents)
            self.verticalLayout.addWidget(self.scrollArea)
            self.verticalLayout_2.addLayout(self.verticalLayout)
            self.pushButton = QtWidgets.QPushButton(self.centralwidget)
            self.pushButton.setObjectName("pushButton")
            self.verticalLayout_2.addWidget(self.pushButton)
            self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
            self.lineEdit.setObjectName("lineEdit")
            self.verticalLayout_2.addWidget(self.lineEdit)
            MainWindow.setCentralWidget(self.centralwidget)
     
            self.retranslateUi(MainWindow)
            self.pushButton.clicked.connect(MainWindow.start_thread)
            self.lineEdit.returnPressed.connect(MainWindow.send_message)
            QtCore.QMetaObject.connectSlotsByName(MainWindow)
     
        def retranslateUi(self, MainWindow):
            _translate = QtCore.QCoreApplication.translate
            MainWindow.setWindowTitle(_translate("MainWindow", "Test"))
            self.pushButton.setText(_translate("MainWindow", "start thread"))
     
     
    class Test(QMainWindow, Ui_MainWindow):
        messageReceived = pyqtSignal(str)
        def __init__(self, parent=None):
            super().__init__(parent)
            self.setupUi(self)
            layout = QVBoxLayout()
            layout.addStretch(1)
            self.scrollAreaWidgetContents.setLayout(layout)
            self.messageReceived.connect(self.incoming_message)
     
        @pyqtSlot()
        def start_thread(self):
            start(self, err_callback)
     
        @pyqtSlot()
        def send_message(self):
            self.write_message(self.lineEdit.text(), "lightblue")
            self.lineEdit.setText("")
     
        def write_message(self, message, color):
            print(f"received {message}")
            label = QLabel(self.scrollAreaWidgetContents)
            label.setText(message)
            label.setStyleSheet(f"background-color:{color}")
            self.scrollAreaWidgetContents.layout().addWidget(label)
     
        def incoming_message(self, message):
            print(f"passed {message}")
            self.write_message(message, "khaki")
     
     
    def start(main, error_callback):
        Thread(target=listen, args=(main, error_callback), daemon=True).start()
     
     
    def listen(main, error_callback):
        while True:
            try:
                sleep(5.0)
                print("Ping !")
                main.messageReceived.emit("Ping !")
            except:
                error_callback("error")
     
     
    def err_callback(message):
        print(message)
     
     
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        test = Test()
        test.show()
        app.exec_()

  3. #3
    Membre expérimenté

    Profil pro
    Enseignant
    Inscrit en
    Juillet 2003
    Messages
    296
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juillet 2003
    Messages : 296
    Par défaut
    Tout bêtement !
    Honte à moi, je pensais bien que c’était un problème de signal, mais je n’avais pas connaissance de pyqtSignal.
    J’aurais appris quelque chose aujourd’hui !

    Merci beaucoup.

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

Discussions similaires

  1. [SWT] Redraw de composant SWT depuis un thread non SWT
    Par Slayne dans le forum SWT/JFace
    Réponses: 3
    Dernier message: 07/02/2008, 09h44
  2. [Débutant] Thread non bloquant
    Par GoustiFruit dans le forum Langage
    Réponses: 4
    Dernier message: 28/11/2007, 17h08
  3. Erreur : Opération inter-threads non valide
    Par cadeau dans le forum C++/CLI
    Réponses: 1
    Dernier message: 12/12/2006, 09h07
  4. [Débutant] boost::thread non-lvalue
    Par Tymk dans le forum Boost
    Réponses: 16
    Dernier message: 18/11/2006, 14h23

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