2017-11-16 6 views
0

Problem BeschreibungPyQt5: Timer in einem Thread

Ich versuche, eine Anwendung zu machen, die Daten sammelt, verarbeitet sie, zeigt sie, und einige Betätigung (Öffnen/Schließen von Ventilen, etc). Als Praxis für zukünftige Anwendungen, bei denen ich strengere Zeitbeschränkungen habe, möchte ich die Datenerfassung und -verarbeitung in einem separaten Thread durchführen.

Mein aktuelles Problem ist, dass es mir sagt, dass ich einen Timer von einem anderen Thread nicht starten kann.

Aktuelle Code Fortschritt

import sys 
import PyQt5 
from PyQt5.QtWidgets import * 
from PyQt5.QtCore import QThread, pyqtSignal 

# This is our window from QtCreator 
import mainwindow_auto 

#thread to capture the process data 
class DataCaptureThread(QThread): 
    def collectProcessData(): 
     print ("Collecting Process Data") 
    #declaring the timer 
    dataCollectionTimer = PyQt5.QtCore.QTimer() 
    dataCollectionTimer.timeout.connect(collectProcessData) 
    def __init__(self): 
     QThread.__init__(self) 

    def run(self): 
     self.dataCollectionTimer.start(1000); 

class MainWindow(QMainWindow, mainwindow_auto.Ui_MainWindow): 
    def __init__(self): 
     super(self.__class__, self).__init__() 
     self.setupUi(self) # gets defined in the UI file 
     self.btnStart.clicked.connect(self.pressedStartBtn) 
     self.btnStop.clicked.connect(self.pressedStopBtn) 

    def pressedStartBtn(self): 
     self.lblAction.setText("STARTED") 
     self.dataCollectionThread = DataCaptureThread() 
     self.dataCollectionThread.start() 
    def pressedStopBtn(self): 
     self.lblAction.setText("STOPPED") 
     self.dataCollectionThread.terminate() 


def main(): 
    # a new app instance 
    app = QApplication(sys.argv) 
    form = MainWindow() 
    form.show() 
    sys.exit(app.exec_()) 

if __name__ == "__main__": 
    main() 

Gibt es Hinweise, wie diese an die Arbeit machen würde geschätzt!

Antwort

1

Sie müssen den QTimer in den DataCaptureThread-Thread verschieben, zusätzlich zu dem, wenn die run-Methode endet, wird der Thread eliminiert, so dass der Timer eliminiert wird. Sie müssen daher die Ausführung dieser Funktion vermeiden, ohne andere Aufgaben zu blockieren. QEventLoop wird dafür verwendet:

class DataCaptureThread(QThread): 
    def collectProcessData(self): 
     print ("Collecting Process Data") 

    def __init__(self, *args, **kwargs): 
     QThread.__init__(self, *args, **kwargs) 
     self.dataCollectionTimer = QTimer() 
     self.dataCollectionTimer.moveToThread(self) 
     self.dataCollectionTimer.timeout.connect(self.collectProcessData) 

    def run(self): 
     self.dataCollectionTimer.start(1000) 
     loop = QEventLoop() 
     loop.exec_() 
+0

Vielen Dank! dies funktionierte nach dem Bearbeiten der Zeile: 'self.dataCollectionTimer.timeout.connect (self.collectProcessData)' zu 'self.dataCollectionTimer.timeout.connect (Lambda: self.collectProcessData)' Andernfalls würde es den Fehler geben: 'TypeError : collectProcessData() nimmt 0 Positionsargumente, aber 1 wurde gegeben "Was ich nicht wirklich verstehe, da keine Argumente übergeben wurden – robotHamster

+0

@robotHamster Wenn es für Sie funktioniert, vergessen Sie nicht, meine Antwort als korrekt zu markieren. – eyllanesc

+0

@ellyanesc ist es in Ordnung, wenn ich das Lambda zu Ihrer Antwort hinzufügen? – robotHamster