Tkinter中的滚动进度条

3 投票
2 回答
5156 浏览
提问于 2025-04-18 10:30

我一直在尝试在Python的tkinter图形界面中设置一个进度条,用来显示某个过程正在运行。这个过程比较长,而且我没有办法准确测量进度,所以我需要使用一种不确定的进度条。不过,我不太喜欢ttk的不确定进度条那种来回跳动的样式。我想要一种可以在进度条上不断滚动的样式,就像这张图片一样。

在这里输入图片描述

用tkinter可以实现吗?

2 个回答

0

我知道这个问题有点老了,但我找到了一种方法,可以帮助其他写tkinter的人。

我最近在做一个tkinter应用,发现处理tkinter对象时,确实需要一个单独的线程。虽然用除了mainloop()以外的方式处理tkinter对象似乎不太被推荐,但对我来说效果很好。我从来没有遇到过main thread is not in main loop的错误,也没有遇到过对象更新不正确的问题。

我稍微修改了一下Corey Goldberg的代码,让它可以正常工作。下面是我的代码(评论中有一些解释)。

import tkinter
import tkinter.ttk as ttk
import threading

def mainProgram(): # secure the main program initialization in its own def
    root = tkinter.Tk()
    frame = ttk.Frame()
    # You need to use indeterminate mode to achieve this
    pb = ttk.Progressbar(frame, length=300, mode='indeterminate')
    frame.pack()
    pb.pack()

    # Create a thread for monitoring loading bar
    # Note the passing of the loading bar as an argument
    barThread = threading.Thread(target=keepLooping, args=(pb,))
    # set thread as daemon (thread will die if parent is killed)
    barThread.daemon=True
    # Start thread, could also use root.after(50, barThread.start()) if desired
    barThread.start()

    pb.start(25)
    root.mainloop()

def keepLooping(bar):
    # Runs thread continuously (till parent dies due to daemon or is killed manually)
    while 1:
        """
        Here's the tricky part.
        The loading bar's position (for any length) is between 0 and 100.
        Its position is calculated as position = value % 100.    
        Resetting bar['value'] to 0 causes it to return to position 0,
        but naturally the bar would keep incrementing forever till it dies.
        It works, but is a bit unnatural.
        """
        if bar['value']==100:
            bar.config(value=0) # could also set it as bar['value']=0    

if __name__=='__main__':
    mainProgram()    

我添加了if __name__=='__main__':这行代码,因为我觉得这样可以更好地定义作用域。

顺便提一下,我发现用while 1:来运行线程会让我的CPU使用率达到20-30%。这个问题很容易解决,只需导入time模块,然后使用time.sleep(0.05),这样可以显著降低CPU的使用率。

在Win8.1和Python 3.5.0上测试过。

2

你试过ttk的确定性进度条吗?你可以让进度条上的进度不断地在条上滚动。

比如说:

#!/usr/bin/env python3

import tkinter
import tkinter.ttk as ttk

root = tkinter.Tk()
frame = ttk.Frame()
pb = ttk.Progressbar(frame, length=300, mode='determinate')
frame.pack()
pb.pack()
pb.start(25)
root.mainloop()

撰写回答