【问题标题】:How to update widgets after thread completed线程完成后如何更新小部件
【发布时间】:2017-07-02 14:43:45
【问题描述】:

下面的代码创建了一个带有标签和按钮的对话框。 按下按钮调用onClick 函数,该函数将calculate 函数作为任务放入queue,触发thread 来完成这项工作。

线程完成后,我想调用dialog.onThreadCompleted 方法,将计算结果作为参数传递给它。然后,此方法将使用thread 执行的计算结果更新self.label。如何实现?

import threading
import Queue as Queue
import functools

global queue
queue = Queue.Queue()


class Thread(QThread):
    def __init__(self, parent=None):
        QThread.__init__(self, parent)

    def run(self):
        global queue
        while True:
            partial = queue.get()
            output = partial()
            queue.task_done()


threads = []
thread = Thread()
threads.append(thread)
thread.start()


def calculate(number):
    for i in range(number):
        i += i
    print 'calculate completed. result: %s' % i
    return i


class Dialog(QDialog):
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        self.setLayout(QVBoxLayout())
        self.label = QLabel(self)
        self.label.setText('This label should display result')
        self.layout().addWidget(self.label)
        button = QPushButton('Start process')
        button.clicked.connect(self.onClick)
        self.layout().addWidget(button)

    def onThreadCompleted(self, result):
        self.label.setText(str(result))

    def onClick(self):
        self.label.setText('Calculation is starting...')
        partial = functools.partial(calculate, number=100000000)
        queue.put(partial)

if __name__ == '__main__':
    app = QApplication([])
    dialog = Dialog()
    dialog.show()
    qApp.exec_()

【问题讨论】:

    标签: python multithreading qt pyqt multiprocessing


    【解决方案1】:

    我决定修改您的代码以便仅使用PyQt(没有QueueThread,只有QThread)。我希望代码是不言自明的。如果没有,请问:)

    from PyQt4 import QtCore, QtGui
    from PyQt4.QtGui import QDialog
    from PyQt4.QtGui import *
    
    import sys
    
    class Thread(QtCore.QObject):
        finished = QtCore.pyqtSignal()
    
        def __init__(self, parent=None):
            QtCore.QObject.__init__(self, parent)
    
            self.TheWorker = QtCore.QThread()
            self.moveToThread(self.TheWorker)
            self.TheWorker.start()
    
            self.number = 0
    
        def calculate(self):
            num = 10000
            for i in range(num):
                self.number += i
            print 'calculate completed. result: %s' % self.number
            self.finished.emit()
    
    class Dialog(QDialog):
        def __init__(self, parent=None):
            QDialog.__init__(self, parent)
    
            # worker which will do the job or you on different thread
            self.myWorker = Thread()
            # catched signal about finishing the job and calls desired method
            self.myWorker.finished.connect(self.onThreadCompleted)
    
            self.setLayout(QVBoxLayout())
            self.label = QLabel(self)
            self.label.setText('This label should display result')
            self.layout().addWidget(self.label)
            button = QPushButton('Start process')
            button.clicked.connect(self.myWorker.calculate)
            self.layout().addWidget(button)
    
        def onThreadCompleted(self):
            self.label.setText(str(self.myWorker.number))
    
        # to quit the thread properly
        def quitThread(self):
            self.myWorker.TheWorker.quit()
            self.myWorker.TheWorker.wait()
    
    if __name__ == '__main__':
        app = QApplication([])
        dialog = Dialog()
        dialog.show()
        qApp.exec_()
        dialog.quitThread()
        sys.exit()
    

    【讨论】:

      猜你喜欢
      • 2018-03-29
      • 2015-06-29
      • 1970-01-01
      • 2012-03-25
      • 2012-02-22
      • 2019-07-09
      • 2013-12-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多