操作期间不更新进度条

2024-04-20 14:04:43 发布

您现在位置:Python中文网/ 问答频道 /正文

在我的python程序中上传一个文件到internet,im使用GTK进度条来显示上传进度。但im面临的问题是,在上传完成之前,进度条不会显示任何活动,然后突然显示上传完成。我使用pycurl发出http请求…我的问题是- 我需要一个多线程应用程序来上传文件并同时更新gui吗?还是我犯了别的错误?

提前谢谢!


Tags: 文件进度条程序应用程序httpgtk错误gui
3条回答

在python 2.x中,整数操作数产生整数除法。试试这个:

#Callback function invoked when download/upload has progress
def progress(download_t, download_d, upload_t, upload_d):
    print 'in fileupload progress'
    mainwin.mainw.prog_bar.set_fraction(float(upload_d) / upload_t)

我要引用PyGTK FAQ

You have created a progress bar inside a window, then you start running a loop that does some work:

while work_left:
    ...do something...
    progressbar.set_fraction(...)

You will notice that the window doesn't even show up, or if it does the progress bar stays frozen until the end of the task. The explanation is simple: gtk is event driven, and you are stealing control away from the gtk main loop, thus preventing it from processing normal GUI update events.

The simplest solution consists on temporarily giving control back to gtk every time the progress is changed:

while work_left:
    ...do something...
    progressbar.set_fraction(...)
    while gtk.events_pending():
        gtk.main_iteration()

Notice that with this solution, the user cannot quit the application (gtk.main_quit would not work because of new loop [gtk.main_iteration()]) until your heavy_work is done.

Another solution consists on using gtk idle functions, which are called by the gtk main loop whenever it has nothing to do. Therefore, gtk is in control, and the idle function has to do a bit of work. It should return True if there's more work to be done, otherwise False.

The best solution (it has no drawbacks) was pointed out by James Henstridge. It is taking advantage of python's generators as idle functions, to make python automatically preserve the state for us. It goes like this:

def my_task(data):
    ...some work...
    while heavy_work_needed:
        ...do heavy work here...
        progress_label.set_text(data) # here we update parts of UI
        # there's more work, return True
        yield True
    # no more work, return False
    yield False

def on_start_my_task_button_click(data):
    task = my_task(data)
    gobject.idle_add(task.next)

The 'while' above is just an example. The only rules are that it should yield True after doing a bit of work and there's more work to do, and it must yield False when the task is done.

更可能的问题是,在您的进度回调(我认为您正在更新进度条)中,您没有调用手动更新显示,即通过GUI的事件循环运行。不过,这只是推测,如果您可以提供更多的代码,那么进一步缩小范围可能会更容易。

您需要手动更新显示的原因是您的主线程也在执行上载,这是它阻塞的地方。

相关问题 更多 >