Advice on GUI timer to display background thread's elapsed time?

拟墨画扇 提交于 2019-12-23 19:15:06

问题


Issue

I have a PyQt GUI where the user presses a button to start a background thread (workerThread, which is subclassed from QThread). I would like to have a timer display (in the form of a QLabel) to show how much time has elapsed since workerThread started, and I would like this timer to stop as soon as the workerThread exits.

Possible solution

I've thought about creating another independent thread (timerThread) that uses a QTimer to send a signal to a slot to update the QLabel in the main GUI thread with the elapsed time every 1 second. This timerThread will exit as soon as it receives a terminate signal from workerThread.

However, I'd have to start timerThread at the same time as WorkerThread, and I'm not sure how to this.

Question

Is there an easier way to do this? Is QTimer even the right approach to start with?


回答1:


Here is one way of doing this. In this example, myThread starts the timerThread as a child process when it's run method is called. It's timeElapsed signal is connected to the timerThreads timeElapsed signal. The timerThread will check each second while the parent isRunning and emit a timeElapsed signal if True:

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import time

from PyQt4 import QtCore, QtGui

class timerThread(QtCore.QThread):
    timeElapsed = QtCore.pyqtSignal(int)

    def __init__(self, parent=None):
        super(timerThread, self).__init__(parent)
        self.timeStart = None

    def start(self, timeStart):
        self.timeStart = timeStart

        return super(timerThread, self).start()

    def run(self):
        while self.parent().isRunning():
            self.timeElapsed.emit(time.time() - self.timeStart)
            time.sleep(1)


class myThread(QtCore.QThread):
    timeElapsed = QtCore.pyqtSignal(int)
    def __init__(self, parent=None):
        super(myThread, self).__init__(parent)

        self.timerThread = timerThread(self)
        self.timerThread.timeElapsed.connect(self.timeElapsed.emit)

    def run(self):
        self.timerThread.start(time.time())

        iterations = 3
        while iterations:
            print "Running {0}".format(self.__class__.__name__)
            iterations -= 1
            time.sleep(2)        


class myWindow(QtGui.QWidget):    
    def __init__(self):
        super(myWindow, self).__init__() 

        self.button = QtGui.QPushButton(self)
        self.button.setText("Start Threading!")
        self.button.clicked.connect(self.on_button_clicked)

        self.label = QtGui.QLabel(self)

        self.layout = QtGui.QVBoxLayout(self)
        self.layout.addWidget(self.button)
        self.layout.addWidget(self.label)

        self.myThread = myThread(self)
        self.myThread.timeElapsed.connect(self.on_myThread_timeElapsed)
        self.myThread.finished.connect(self.on_myThread_finished)

    @QtCore.pyqtSlot()
    def on_button_clicked(self):
        self.myThread.start()

    @QtCore.pyqtSlot(int)
    def on_myThread_timeElapsed(self, seconds):
        self.label.setText("Time Elapsed: {0}".format(seconds))

    @QtCore.pyqtSlot()
    def on_myThread_finished(self):
        print "Done"

if __name__ == "__main__":
    import sys

    app = QtGui.QApplication(sys.argv)
    app.setApplicationName('myWindow')

    main = myWindow()
    main.show()

    sys.exit(app.exec_())


来源:https://stackoverflow.com/questions/14368400/advice-on-gui-timer-to-display-background-threads-elapsed-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!