Python PyQT: How to call a GUI function from a worker thread?

前端 未结 1 562
没有蜡笔的小新
没有蜡笔的小新 2021-01-01 04:02

I have a pyqt gui and calling a long process (ffmpeg) which I put on a separate thread to not block the gui. I then want to update a progress bar when one command of a longe

相关标签:
1条回答
  • 2021-01-01 04:51

    In short: Move to QThread and use Qt's signals and slots, they are the preferred way to communicate between threads.

    This answer provides some examples how this could look like: https://stackoverflow.com/a/6789205/2319400

    In your case, using the "SomeObject" version from the above could look like this:

    class Worker(QtCore.QObject):
    
        madeProgress = QtCore.pyqtSignal([int])
        finished = QtCore.pyqtSignal()
    
        def __init__(self, cmdlist):
            self.cmdlist = cmdlist
    
        def run(self):
            for icmd, cmd in enumerate(self.cmdlist):
                # execute your work
                # processCommand(cmd)
    
                # signal that we've made progress
                self.madeProgress.emit(icmd)
    
            # emit the finished signal - we're done
            self.finished.emit()
    

    Then move this worker to a QThread instance you create. Following the pattern from the linked answer, you can then connect the madeProgress signal to the setValue slot of a progressbar:

    workerThread = QThread()
    workerObject = Worker(cmdlist)
    workerObject.moveToThread(workerThread)
    workerThread.started.connect(workerObject.run)
    workerObject.finished.connect(workerThread.quit)
    
    # create a progressbar with min/max according to
    # the length of your cmdlist
    progressBar = QProgressBar()
    progressBar.setRange(0, len(cmdlist))
    
    # connect the worker's progress signal with the progressbar
    workerObject.madeProgress.connect(progressBar.setValue)
    
    # start the thread (starting your worker at the same time)
    workerThread.start()
    
    0 讨论(0)
提交回复
热议问题