在循环中更新PyQt4 GUI

时间:2015-05-10 21:17:16

标签: multithreading python-2.7 user-interface pyqt4 qthread

我想在我的GUI中显示计算进度。为此,我想在每次计算时更新我的​​PyQt4标签。我知道我应该使用线程来做它,但它不起作用。没有任何变化,并且在while循环完成后,标签将更新为“100%”。即使线程正在运行,该值仍然无法顺利更新。我的代码中有评论说明了什么。请帮帮我:)。

from PyQt4 import QtGui, QtCore
import time

class MyThread(QtCore.QThread):
    trigger = QtCore.pyqtSignal(int)
    def __init__(self, progress, parent=None):
        super(MyThread, self).__init__(parent)
        self.progress = progress #progress is a PyQt4 label object

    def update_progress(self, value):
        self.progress.setText(QtGui.QApplication.translate("Dialog", "Progress: %s " % value, None))
        print "I was called", value
        print self.progress #prints <PyQt4.QtGui.QLabel object at 0x0000000008151708>
        #as you can see the object is passed all right
    def run(self, value):
        self.trigger.emit(value)

class Calculus:
    def __init__(self):
        print "object created"

    @staticmethod
    def euler(b,h,progress):    
        #progress is a PyQt4 label object, b and h are some integers
        actions_done = 0
        actions_number = b / h

        thread = MyThread(progress)#create a thread
        thread.trigger.connect(thread.update_progress)#connect it with a update function
        thread.start()#start the thread


        while t <= b:
            actions_done+=1
            progress_value = (actions_done/actions_number)*100

            thread.run(progress_value)#emit signal?
            t += h

        thread.terminate()

@EDIT,这是我的解决方案,但内存泄漏问题

from PyQt4 import QtGui

class Calculus:
    def __init__(self):
        print "object created"

    @staticmethod
    def update_progress(self,value,ui_object): 
        ui_object.setText(QtGui.QApplication.translate("Dialog", "Progress: %s %%" % value, None))

        #MEMORY LEAK WHEN UPDATING TOO MUCH (H=0.0001 AND B=1000)
        QtGui.QApplication.processEvents() #update gui for pyqt



    @staticmethod
    def euler(b,h,progress):
        actions_done = 0
        actions_number = b * (1./h) #t = t+h. When h = 0.01 we need to perform t=t+h 100(1/h) times to get 1. 
                                    #when t varies from 0 to b, then we need to multiply this 1 * b(end time)
                                    #so we get b * (1/h) as a number of actions to perform

        scale = actions_number * 0.01

        while t <= b:
            actions_done+=1
            progress_value = (actions_done/actions_number)*100

            if (actions_done % scale == 0):
                Calculus.update_progress(None,progress_value, progress)         

            t += h

1 个答案:

答案 0 :(得分:1)

以您的方式调用thread.run()并不会按照您的想法执行。目前它只是在主线程中执行thread.run()方法。

调用thread.start()启动线程,并自动调用thread.run()方法。因此,您需要while循环内部 thread.run()方法。

这是因为你想要完全控制到线程,并完成euler方法,以便控制可以返回到GUI事件循环(因此它可以处理重绘,以及更新方法进度条)尽快。您不应该尝试从主线程管理线程执行。

相关问题