Tkinter进度栏挂起程序,无法继续

时间:2019-03-28 17:57:15

标签: python tkinter progress

我试图使用线程来实现Tkinter进度条,只是为了查看程序何时运行,并在程序结束时关闭进度条。

import tkinter
import ttk
import time
import threading

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()


def process_of_unknown_duration(root):
    time.sleep(5)
    root.destroy()


def pBar():
    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()


if __name__ == '__main__':
    pBar()
    #some function

我的问题是,一旦进度条启动,该程序就会挂起,并且不会执行其他任何操作。有提示吗?

2 个答案:

答案 0 :(得分:1)

这是因为您的通话root.mainloop() is blocking the execution of your code。它基本上代表了UI的循环。您可能要查看this answer上由按钮启动的进度条。

答案 1 :(得分:0)

您仍然对此问题感兴趣吗?在简单的情况下,请尝试对根对象使用update()方法,而不要使用线程。我提供了以下带有全局变量的简化演示解决方案,作为后续开发的起点。

import tkinter
from tkinter import *
from tkinter import ttk
import time

root1 = Tk()

progrBar1 = None  # The main progress bar
win2 = None

def click_but1():
    global win2, progrBar2
    if win2 is None:
        win2 = Toplevel()  # Secondary window
        win2.title('Secondary')
        win2.protocol('WM_DELETE_WINDOW', clickClose)  # close the secondary window on [x] pressing
        but2 = Button(win2, text='Close', command=clickClose)
        but2.pack()
        but3 = Button(win2, text='Process', command=clickProcess)
        but3.pack()
        progrBar2 = ttk.Progressbar(win2, orient = 'horizontal', length = 300, mode = 'determinate')
        progrBar2.pack()
    if progrBar1:
        progrBar1.start(50)

def clickClose():
    global win2
    progrBar1.stop()
    win2.destroy()
    win2=None

def clickProcess():
    my_func()

def my_func():
    global progrBar2
    range1, range2 = 20, 40
    step1 = 100/range1
    for i in range(range1):
        for j in range(range2):
            time.sleep(0.01)
        progrBar2.step(step1)
        root1.update()  # the "update" method

root1.title('Root')  # Main window
progrBar1 = ttk.Progressbar(root1, orient = 'horizontal', mode = 'indeterminate')  # The main progress bar
but1 = Button(root1, text = 'Start', command = click_but1)
but1.pack()
progrBar1.pack()
root1.mainloop()

第一个(主)窗口中的进度条仅在第二个窗口存在时才移动。关闭第二个窗口后,该指针栏将停止并返回到初始位置。辅助窗口具有自己的进度条,用于演示,并通过update()方法显示窗口之间的交互。