Python使用progressBars设置四个步骤

时间:2010-05-16 18:19:17

标签: python multithreading progress-bar pygtk

我遇到以下代码的问题。当我运行它时,进度条将按照惯例脉冲大约10秒,然后继续下载并显示进度,但完成后它将不会继续进行下一步它只是锁定。

import sys
import time
import pygtk
import gtk
import gobject
import threading
import urllib
import urlparse

class WorkerThread(threading.Thread):

    def __init__ (self, function, parent, arg = None):
        threading.Thread.__init__(self)
        self.function = function
        self.parent = parent
        self.arg = arg
        self.parent.still_working = True

    def run(self): # when does "run" get executed?
        self.parent.still_working = True      
        if self.arg == None:
            self.function()
        else:
            self.function(self.arg)

        self.parent.still_working = False    

    def stop(self):
        self = None

class MainWindow:
    def __init__(self):
        gtk.gdk.threads_init()
        self.wTree = gtk.Builder()
        self.wTree.add_from_file("gui.glade")
        self.mainWindows()

    def mainWindows(self):
        self.mainWindow = self.wTree.get_object("frmMain")

        dic = { 
            "on_btnNext_clicked" : self.mainWindowNext,
        }
        self.wTree.connect_signals(dic)

        self.mainWindow.show()
        self.installerStep = 0 # 0 = none, 1 = preinstall, 2 = download, 3 = install info, 4 = install
        #gtk.main()
        self.mainWindowNext()

    def pulse(self):
        self.wTree.get_object("progress").pulse()

        if self.still_working == False:
            self.mainWindowNext()

        return self.still_working

    def preinstallStep(self):
        self.wTree.get_object("progress").set_fraction(0)
        self.wTree.get_object("btnNext").set_sensitive(0)
        self.wTree.get_object("notebook1").set_current_page(0)
        self.installerStep = 1
        WT = WorkerThread(self.heavyWork, self) #Would do a heavy function here like setup some thing
        WT.start()

        gobject.timeout_add(75, self.pulse)

    def downloadStep(self):
        self.wTree.get_object("progress").set_fraction(0)
        self.wTree.get_object("btnNext").set_sensitive(0)
        self.wTree.get_object("notebook1").set_current_page(0)
        self.installerStep = 2
        urllib.urlretrieve('http://mozilla.mirrors.evolva.ro//firefox/releases/3.6.3/win32/en-US/Firefox%20Setup%203.6.3.exe', '/tmp/firefox.exe', self.updateHook)

        self.mainWindowNext()

    def updateHook(self, blocks, blockSize, totalSize):
        percentage = float ( blocks * blockSize ) / totalSize
        if percentage > 1:
            percentage = 1

        self.wTree.get_object("progress").set_fraction(percentage)

        while gtk.events_pending():
            gtk.main_iteration()

    def installInfoStep(self):
        self.wTree.get_object("btnNext").set_sensitive(1)
        self.wTree.get_object("notebook1").set_current_page(1)
        self.installerStep = 3

    def installStep(self):
        self.wTree.get_object("progress").set_fraction(0)
        self.wTree.get_object("btnNext").set_sensitive(0)
        self.wTree.get_object("notebook1").set_current_page(0)
        self.installerStep = 4

        WT = WorkerThread(self.heavyWork, self) #Would do a heavy function here like setup some thing
        WT.start()

        gobject.timeout_add(75, self.pulse)

    def mainWindowNext(self, widget = None):
        if self.installerStep == 0:
            self.preinstallStep()
        elif self.installerStep == 1:
            self.downloadStep()
        elif self.installerStep == 2:
            self.installInfoStep()
        elif self.installerStep == 3:
            self.installStep()
        elif self.installerStep == 4:
            sys.exit(0)

    def heavyWork(self):
        time.sleep(10)

if __name__ == '__main__':
    MainWindow()
    gtk.main()

我觉得它与它有关:

while gtk.events_pending():
    gtk.main_iteration()

有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

不要这样做:

while gtk.events_pending():
   gtk.main_iteration()

除非你真的知道自己在做什么。如果你真的这样做,那就去做like this

def refresh_gui(delay=0.0001, wait=0.0001):
    """Use up all the events waiting to be run

    :param delay: Time to wait before using events
    :param wait: Time to wait between iterations of events

    This function will block until all pending events are emitted. This is
    useful in testing to ensure signals and other asynchronous functionality
    is required to take place.

    (c) PyGTKHelpers Authors 2005-2010
    """
    time.sleep(delay)
    while gtk.events_pending():
        gtk.main_iteration_do(block=False)
        time.sleep(wait)

使用block = False和一些延迟。

如果你想使用线程,我个人不建议像那样继承Thread(没有意义),相反,我会建议一个方法like this,它有一个更新进度条的例子。 / p>