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 :

__init__ d'un QThread


Sujet :

PyQt Python

  1. #1
    Membre éclairé Avatar de bastou93
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2010
    Messages
    217
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 217
    Par défaut __init__ d'un QThread
    Bonjour à tous,

    Je suis un peu perdu sur ce qu'il vient de m'arriver

    Je développe un logiciel sur une machine, qui utilise un QThread que j'utilise comme dans la doc QT5:

    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
    class WorkerThread : public QThread
    {
        Q_OBJECT
        void run() Q_DECL_OVERRIDE {
            QString result;
            /* expensive or blocking operation  */
            emit resultReady(result);
        }
    signals:
        void resultReady(const QString &s);
    };
     
    void MyObject::startWorkInAThread()
    {
        WorkerThread *workerThread = new WorkerThread(this);
        connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);
        connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
        workerThread->start();
    }


    Voici le code ciblé qui me pause problème:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Script(QThread):
     
        def __init__(self, code):
     
            super(Script, self).__init__()      
            self.code = code
    Cela marche sans problème sur mon poste! Sauf que voila j'ai voulu tester sur une autre machine et la j'ai une erreur lors de l'instantiation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      File "C:\HDF\v0\01_soft\dts\core\script.py", line 34, in __init__
        super(Script, self).__init__()
    TypeError: __call__() missing 1 required positional argument: 'qthread'
    Si je change ce code par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    super(Script, self).__init__(self)
    Il se met à marcher sur cette machine mais plus sur celle ou je développé initialement....

    Pareil si je crée un exécutable avec cxfreeze, le meme exe marche sur les 2 machines, celui avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    super(Script, self).__init__()
    Si vous avez des idées... Je ne maitrise pas beaucoup tout ce qui est instanciation, init en python c'est sans doute pour cela que je coince...

    Merci d'avance,

    Bastien

  2. #2
    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,

    A essayer en remplacement de super:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Monthread(QThread):
     
        def __init__(self, parent=None):
            QThread.__init__(self, parent)
            ....

  3. #3
    Membre éclairé Avatar de bastou93
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2010
    Messages
    217
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 217
    Par défaut
    Merci tyranos pour ta réponse

    Voici le code implémenté:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class Script(QThread):    
        def __init__(self, code, parent = None):
                QThread.__init__(self, parent) 
                self.code = code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Traceback (most recent call last):
    ...
      File "xxx", line 35, in __init__
        QThread.__init__(self, parent)
      File "C:\src\ide\bin\3.3\src/debug/tserver\dbgutils.pyc", line 1134, in __get__
    TypeError: self must not be None
    sur une de mes machines mais sur l'autre IMPEC... A savoir que je suis en python 3.3 sur les 2 machines et QT 5

    je comprends vraiment pas

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 677
    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 677
    Par défaut
    Salut,

    A partir du moment ou la documentation QThread explique de ne pas s/classer QThread mais de *voir la doc*, pourquoi s'obstiner a essayer de s/classer?

    oui je suis chiant et c'est comme ça.

    - 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 wiztricks,

    Citation Envoyé par wiztricks Voir le message
    oui je suis chiant et c'est comme ça.
    Quand c'est un pour un bon motif, ce n'est pas grave

    Mais on n'a pas la même lecture de la doc. J'ai lu quelques précautions à prendre pour créer des slots supplémentaires ou pour utiliser terminate(), mais pas de dissuasion clairement exprimée vis-à-vis du sous-classement de QThread.

    Et puis je note qu'il y a plusieurs exemples fournis, tant en C++ qu'en PyQt4 avec sous-classement de QThread, ce qui serait bizarre si c'était mal.

    Le fait qu'il y ait des exemples avec sous-classement de QThread est d'ailleurs intéressant pour le PO (mandelbrot.pyw, semaphores.py, waitconditions.py): il faut regarder comment ils ont fait et s'en inspirer

    En ce qui me concerne, j'utilise cela souvent sans aucun problème.

    Je sais qu'il y a un gars qui a exprimé cette opinion sur le sous-classement des threads, mais ce n'est qu'une opinion. Tant que c'est permis par la doc, on peut faire si c'est utile.

    Ci-dessous un petit code de test (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
    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
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    from __future__ import division
    # Python 2.7
     
    import sys, os, time
     
    from PyQt4 import QtCore, QtGui
     
    #############################################################################
    class Operationlongue(QtCore.QThread):
     
        # création des nouveaux signaux
        info = QtCore.pyqtSignal(int)
        fini = QtCore.pyqtSignal(bool)
     
        #========================================================================
        def __init__(self, parent=None):
            super(Operationlongue, self).__init__(parent)
     
            self.stop = False
     
        #========================================================================
        def run(self):
            """partie qui s'exécute en tâche de fond"""
            for i in range(0, 101):
                if self.stop:
                    break # arrêt anticipé demandé
                time.sleep(0.05)
                self.info.emit(i)
            # fin du thread
            self.fini.emit(self.stop)
     
        #========================================================================
        def arreter(self):
            """pour arrêter avant la fin normale"""
            self.stop = True
     
    #############################################################################
    class Fenetre(QtGui.QWidget):
     
        #========================================================================
        def __init__(self, parent=None):
            super(Fenetre,self).__init__(parent)
     
            self.depart = QtGui.QPushButton(u"Départ", self)
            self.depart.clicked.connect(self.lancement)
     
            self.arret = QtGui.QPushButton(u"Arrêt", self)
            self.arret.clicked.connect(self.arreter)
     
            self.barre = QtGui.QProgressBar(self)
            self.barre.setRange(0, 100)
     
            self.barre.setValue(0)
     
            posit = QtGui.QGridLayout()
            posit.addWidget(self.depart, 0, 0)
            posit.addWidget(self.arret, 1, 0)
            posit.addWidget(self.barre, 2, 0)
            self.setLayout(posit)        
     
            self.operationlongue = None
     
        #========================================================================
        def lancement(self, ok):
     
            if self.operationlongue==None or not self.operationlongue.isRunning():
                # initialisation de la barre de progression
                self.barre.reset()
                self.barre.setRange(0, 100)
                self.barre.setValue(0)
                # démarre l'opération longue dans le thread
                self.operationlongue = Operationlongue()
                self.operationlongue.info.connect(self.progression)
                self.operationlongue.fini.connect(self.stop)
                self.operationlongue.start()
     
        #========================================================================
        @QtCore.pyqtSlot(int)
        def progression(self, i):
            """lancé à chaque réception d'info émis par le thread"""
            self.barre.setValue(i)
            QtCore.QCoreApplication.processEvents() # force le rafraichissement
     
        #========================================================================
        @QtCore.pyqtSlot()
        def arreter(self):
            """pour arrêter avant la fin"""
            if self.operationlongue!=None and self.operationlongue.isRunning():
                self.operationlongue.arreter()
     
        #========================================================================
        @QtCore.pyqtSlot(bool)
        def stop(self, fin):
            """Lancé quand le thread se termine"""
            if fin:
                # fin anticipée demandée
                QtGui.QMessageBox.information(self,
                    u"Opération longue",
                    u"Arrêt avant la fin!")
            else:    
            # fin normale
                self.barre.setValue(100)
                QtGui.QMessageBox.information(self,
                    u"Opération longue",
                    u"Terminée!")
     
        #========================================================================
        def closeEvent(self, event):
            """lancé à la fermeture de la fenêtre quelqu'en soit la méthode"""
            if self.operationlongue.isRunning():
                self.operationlongue.terminate()
            event.accept()
     
    #############################################################################
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        fen = Fenetre()
        fen.show()
        sys.exit(app.exec_())

Discussions similaires

  1. [QThread] QProcess et QSemaphore
    Par slymira dans le forum Multithreading
    Réponses: 11
    Dernier message: 29/11/2007, 11h40
  2. [QThread] QThread qui fait figger le programme
    Par alpha_one_x86 dans le forum Multithreading
    Réponses: 1
    Dernier message: 29/11/2007, 10h16
  3. [QThread] ne marche pas
    Par alpha_one_x86 dans le forum Multithreading
    Réponses: 11
    Dernier message: 23/11/2007, 09h13
  4. [Thread] QThread et QSocket
    Par G3G3 dans le forum Multithreading
    Réponses: 7
    Dernier message: 30/10/2007, 20h25

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