【问题标题】:Python Four steps setup with progressBarsPython 四步设置进度条
【发布时间】:2010-05-16 18:19:16
【问题描述】:

下面的代码有问题。当我运行它时,进度条会按预期脉冲大约 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()

有更好的方法吗?

【问题讨论】:

  • 你可以编辑它,使它不是每行双倍行距,并且标题用“for”而不是“4”吗?
  • 4 代表“四个”而不是“代表”,因为它在设置中有 4 个步骤。是的,我可以更改间距,发布时在编辑器中不是双倍行距。
  • 嘿,等一下? Python 4 出来了,我还停留在 Python 2 上? ... 啊对。 :(

标签: python multithreading progress-bar pygtk


【解决方案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,它有一个更新进度条的示例。

【讨论】:

  • 感谢您的回复,我回家后会尝试您的建议。我几乎放弃了让它发挥作用的所有希望。
猜你喜欢
  • 1970-01-01
  • 2012-07-03
  • 1970-01-01
  • 2011-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-27
  • 1970-01-01
相关资源
最近更新 更多