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 :

Utiliser correctement les threads


Sujet :

PyQt Python

  1. #1
    Membre habitué
    Homme Profil pro
    Directeur technique
    Inscrit en
    Janvier 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Janvier 2008
    Messages : 9
    Par défaut Utiliser correctement les threads
    Bonjour a tous,

    Je suis en train de faire une application qui a pour role de scanner des dossiers sur un réseau
    en continu afin de produire un rapport dans une base de donnee, accessible via une interface en Qt.

    Je suis donc obligé de créer une application qui a deux threads :
    Le premier thread est celui de l'application principale, qui affichera le contenu de la BDD.
    Et un second thread qui est le "scanner de dossiers".

    Pour bien reussir cette application, j'ai décidé de commencer par un genre de test.
    Ce test est un compteur avec 3 boutons : Start, Stop et Reset.
    J'ai parcouru de nombreux forums, j'ai lu tout un tas d'article et de docs, mais je dois avouer que je ne me sent pas encore a l'aise avec le concept.

    Pour l'instant je n'arrive pas à arrêter mon compteur une fois qu'il est démarré.
    Le thread se termine sans répondre.

    Voici le code du programme, j'espère que vous pourrez m'aider !
    Vous pouvez l'executer directement, vous comprendrez tout de suite le problème : Si on appuie sur start, plus rien ne répond...

    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
    122
    123
    124
    125
    from PyQt4 import QtCore, QtGui
    import time
     
    class counter(QtCore.QObject) :
    	# le compteur 
    	def __init__(self) :
    		super(counter,self).__init__()
    		self.sh = None 
    		self.stop = False 
    		self.count = 0 
    		self.maxCount = 50 
     
    	def setSH(self,sh) :
    		self.sh = sh 
     
    	def startCount(self) :
    		self.sh.textSignal.emit( "Starting..." )
    		self.stop = False 
    		while not self.stop : 
    			self.sh.textSignal.emit( str( self.count ) )
    			self.count = self.count + 1
    			time.sleep(0.1)
    			if self.count > self.maxCount : 
    				self.stop = True
    				self.sh.textSignal.emit( "Finished..." )
     
    	def stopCount(self) :
    		self.sh.textSignal.emit( "Stopping..." )	
    		self.stop = True
     
    	def resetCount(self) :
    		self.sh.textSignal.emit( "Reseting..." )	
    		self.count = 0 
     
    	def quit(self) :
    		self.stop = True
    		self.parent.quit()
     
     
    class signalsHolder(QtCore.QObject) : 
    	# un conteneur pour mes signaux
    	startSignal = QtCore.pyqtSignal()
    	stopSignal 	= QtCore.pyqtSignal()
    	resetSignal = QtCore.pyqtSignal() 
    	killThreadSignal = QtCore.pyqtSignal() 
    	textSignal 	= QtCore.pyqtSignal(str)
     
    class cpt(QtGui.QMainWindow):
    	#l'application principale, avec l'interface et les boutons et un log
    	def __init__(self):	
    		super(cpt, self).__init__()
    		self.sh = None 
     
    		self.log = QtGui.QPlainTextEdit()
    		self.log.setPlainText( "Welcome ! " ) 
     
    		startScanButton = QtGui.QPushButton("Start")
    		startScanButton.clicked.connect( self.startThread )		
    		stopScanButton = QtGui.QPushButton("Stop")
    		stopScanButton.clicked.connect( self.stopThread )
    		resetScanButton = QtGui.QPushButton("Reset")
    		resetScanButton.clicked.connect( self.resetThread )
     
    		buttonsBarlayout = QtGui.QHBoxLayout()
    		buttonsBarlayout.addWidget( startScanButton )
    		buttonsBarlayout.addWidget( stopScanButton )
    		buttonsBarlayout.addWidget( resetScanButton )
     
    		self.buttonsBar = QtGui.QGroupBox("Actions : ")
    		self.buttonsBar.setLayout(buttonsBarlayout)
     
    		self.mainLayout = QtGui.QGridLayout()
    		self.mainLayout.addWidget( self.buttonsBar , 		0,0)
    		self.mainLayout.addWidget( self.log ,				1,0)
     
    		mainWidget = QtGui.QWidget()
    		mainWidget.setLayout(self.mainLayout)
    		self.setCentralWidget(mainWidget)
     
    	def setSH(self,sh) :
    		self.sh = sh 
     
    	def atl(self,infos) :
    		# Ajoute des infos dans le log
    		self.log.appendPlainText(infos)
     
    	def startThread(self) : 
    		self.sh.startSignal.emit()
     
    	def stopThread(self) :
    		self.sh.stopSignal.emit()
     
    	def resetThread(self) :
    		self.sh.resetSignal.emit()
     
    	def quit(self) :
    		self.sh.killThreadSignal.emit()
     
     
    def main() :
    	import sys
    	app = QtGui.QApplication(sys.argv)
    	mainWindow = cpt()
     
    	sh =  signalsHolder()
    	mainWindow.setSH(sh)
     
    	thisCounter = counter()
    	thisCounter.setSH(sh)
     
    	sh.startSignal.connect(thisCounter.startCount)
    	sh.stopSignal.connect(thisCounter.stopCount)
    	sh.resetSignal.connect(thisCounter.resetCount)
    	sh.textSignal.connect(mainWindow.atl)
     
    	thisThread = QtCore.QThread(None)
    	sh.killThreadSignal.connect(thisCounter.quit) 
    	thisCounter.moveToThread(thisThread)
    	thisThread.start()
     
    	mainWindow.show()
    	sys.exit( app.exec_() )
     
    if __name__ == '__main__':
    	main()

  2. #2
    Membre expérimenté Avatar de ashren
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 101
    Par défaut
    Bonjour,

    pour commencer, tu n'as fais usage d'aucun thread, uniquement du mécanisme signal/slot de Qt4.

    Voici un exemple d'utilisation avec QThread :

    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
     
    from PyQt4 import QtGui, QtCore
    import time
     
    class MyThread(QtCore.QThread):
        valueChanged = QtCore.pyqtSignal(int)
     
        def __init__(self, parent=None):
            super(MyThread, self).__init__(parent=parent)
            self.__value = 0
     
        def run(self):
            for i in range(100):
                self.__value = i
                self.valueChanged.emit(self.__value)
                time.sleep(0.1)
     
    class WindowTest(QtGui.QWidget):
        def __init__(self):
            super(WindowTest, self).__init__()
            self.setLayout(QtGui.QBoxLayout(QtGui.QBoxLayout.TopToBottom))
            self.pbar = QtGui.QProgressBar(self)
            self.layout().addWidget(self.pbar)
     
            self.btnStart = QtGui.QPushButton("Start", self)
            self.btnStart.clicked.connect(self.__doStart)
            self.layout().addWidget(self.btnStart)
     
            self.btnStop = QtGui.QPushButton("Stop", self)
            self.btnStop.clicked.connect(self.__doStop)
            self.layout().addWidget(self.btnStop)
     
            self.__thread = MyThread(self)
            self.__thread.valueChanged.connect(self.pbar.setValue)
     
        def __doStart(self):
            self.__thread.start()
     
        def __doStop(self):
            if self.__thread.isRunning():
                self.__thread.terminate()
     
    if __name__ == '__main__':
        app = QtGui.QApplication([])
        win = WindowTest()
        win.show()
        app.exec_()

Discussions similaires

  1. Réponses: 0
    Dernier message: 29/12/2010, 00h06
  2. [GRASP] Est-ce que j'utilise correctement les design pattern?
    Par Tourix dans le forum Design Patterns
    Réponses: 7
    Dernier message: 21/06/2006, 18h27
  3. Comment utiliser les Threads en VC++?
    Par mambo dans le forum MFC
    Réponses: 2
    Dernier message: 16/06/2006, 14h04
  4. BeginInvoke (utiliser les threads)
    Par the big ben 5 dans le forum Delphi
    Réponses: 6
    Dernier message: 16/05/2006, 18h30
  5. comment utiliser correctement les sessions?
    Par cladsam dans le forum Langage
    Réponses: 5
    Dernier message: 06/02/2006, 11h56

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