Tkinter:持续时间不确定的进度条

6
我希望在Tkinter中实现一个进度条,具备以下要求:
  • 进度条是主窗口中唯一的元素
  • 可以通过启动命令开始,不需要按任何按钮
  • 能够等待一个未知持续时间的任务完成
  • 只要任务未完成,进度条的指示器就会持续移动
  • 可以通过停止命令关闭,不需要按任何停止条
到目前为止,我有以下代码:
import Tkinter
import ttk
import time

def task(root):
    root.mainloop()

root = Tkinter.Tk()
ft = ttk.Frame()
ft.pack(expand=True, fill=Tkinter.BOTH, side=Tkinter.TOP)
pb_hD = ttk.Progressbar(ft, orient='horizontal', mode='indeterminate')
pb_hD.pack(expand=True, fill=Tkinter.BOTH, side=Tkinter.TOP)
pb_hD.start(50)
root.after(0,task(root))
time.sleep(5) # to be replaced by process of unknown duration
root.destroy()

这里的问题是进度条在5秒结束后没有停止。

有人能帮我找到错误吗?

1个回答

11

一旦主循环激活,脚本在根被销毁之前不会移动到下一行。可能有其他方法来实现这一点,但我更喜欢使用线程。

像这样:

import Tkinter
import ttk
import time
import threading

#Define your Progress Bar function, 
def task(root):
    ft = ttk.Frame()
    ft.pack(expand=True, fill=Tkinter.BOTH, side=Tkinter.TOP)
    pb_hD = ttk.Progressbar(ft, orient='horizontal', mode='indeterminate')
    pb_hD.pack(expand=True, fill=Tkinter.BOTH, side=Tkinter.TOP)
    pb_hD.start(50)
    root.mainloop()

# Define the process of unknown duration with root as one of the input And once done, add root.quit() at the end.
def process_of_unknown_duration(root):
    time.sleep(5)
    print 'Done'
    root.destroy()

# Now define our Main Functions, which will first define root, then call for call for "task(root)" --- that's your progressbar, and then call for thread1 simultaneously which will  execute your process_of_unknown_duration and at the end destroy/quit the root.

def Main():
    root = Tkinter.Tk()
    t1=threading.Thread(target=process_of_unknown_duration, args=(root,))
    t1.start()
    task(root)  # This will block while the mainloop runs
    t1.join()

#Now just run the functions by calling our Main() function,
if __name__ == '__main__':
    Main()

如果这有帮助,请告诉我。


状态栏随后将被集成到主程序中,sys.exit()也会关闭主程序。现在唯一的问题是,上面的代码会打开一个包含状态栏的新Tkinter窗口,该窗口在状态栏停止后不会关闭。代码本身运行没有错误。 - Rickson
我不明白。解决方案非常简单。但我需要你的帮助更好地理解。只有3个函数。1)ProgressBar,2)未知持续时间的进程,3)销毁ProgressBar。...或者还有第四个函数吗?无论情况如何。你想什么时候执行sys.exit()?进度条关闭后立即执行?还是等待另一个函数执行然后再执行sys.exit()? - Md. Mohsin
好的,上面的代码必须打开一个新窗口才能显示状态栏。但是如果状态栏已经停止工作,那么这个窗口必须再次关闭。在process_of_unknown_duration完成后可以执行sys.exit() - Rickson
而在root.destroy()下面添加sys.exit()有什么问题呢? 这是我的理解。1)脚本开始2)您的函数(process_of_unknown_duration)开始3)同时进度条开始4)process_of_unknown_duration结束5)立即销毁进度条。...现在没有什么了...那么在root.destroy()之后添加sys.exit()有什么问题呢...脚本已经完成了!我错过了什么吗? - Md. Mohsin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接