Tkinter:调用函数时更新进度条

时间:2018-07-12 06:35:22

标签: python python-3.x tkinter python-3.6

想象下面的简单示例:

def doNothing():
  sleep(0.5)
  barVar.set(10)
  sleep(0.5)
  barVar.set(20)
  sleep(0.5)
  barVar.set(30)

mainWindow = Tk()
barVar = DoubleVar()
barVar.set(0)
bar = Progressbar(mainWindow, length=200, style='black.Horizontal.TProgressbar', variable=barVar, mode='determinate')
bar.grid(row=1, column=0)
button= Button(mainWindow, text='Click', command=doNothing)
button.grid(row=0, column=0)
mainWindow.mainloop()

我得到的结果,运行该按钮时,单击该按钮时进度条已经处于30%的位置,前方没有进度。如附件所示:

enter image description here

我需要什么 我可以看到我面前的进度 (先不挂机,然后突然30%)

更新: 我根据@Bernhard的答案更新了代码,但仍然 看不到我面前的进度 。等待1.5秒后,突然跳了30%

第二次更新: 我在这里只是将睡眠用作模拟过程的过程,该过程需要时间,例如通过ssh连接并获取一些信息。

3 个答案:

答案 0 :(得分:1)

请勿在tkinter中使用sleep()。您遇到问题的全部原因是sleep()将冻结tkinter,直到完成其计数为止,因此您看到的是冻结的程序,并且当该程序最终发布时,在下一次mainloop更新中它已设置为30%。

相反,我们需要使用Tkinter的内置方法after(),如下所述。

将tkinter导入为tk 将tkinter.ttk导入为ttk

mainWindow = tk.Tk()

def update_progress_bar():
    x = barVar.get()
    if x < 100:
        barVar.set(x+10)
        mainWindow.after(500, update_progress_bar)
    else:
        print("Complete")


barVar = tk.DoubleVar()
barVar.set(0)
bar = ttk.Progressbar(mainWindow, length=200, style='black.Horizontal.TProgressbar', variable=barVar, mode='determinate')
bar.grid(row=1, column=0)
button= tk.Button(mainWindow, text='Click', command=update_progress_bar)
button.grid(row=0, column=0)

mainWindow.mainloop()

如果希望条形图平滑移动,则需要加快函数调用的速度,并减少对DoubbleVar的添加。

import tkinter as tk
import tkinter.ttk as ttk


mainWindow = tk.Tk()

def update_progress_bar():
    x = barVar.get()
    if x < 100:
        barVar.set(x+0.5)
        mainWindow.after(50, update_progress_bar)
    else:
        print("Complete")


barVar = tk.DoubleVar()
barVar.set(0)
bar = ttk.Progressbar(mainWindow, length=200, style='black.Horizontal.TProgressbar', variable=barVar, mode='determinate')
bar.grid(row=1, column=0)
button= tk.Button(mainWindow, text='Click', command=update_progress_bar)
button.grid(row=0, column=0)

mainWindow.mainloop()

答案 1 :(得分:0)

由于初始化对接时要调用函数,因此需要在命令=(barVar))中松开'(barVar')。这样,您可以将函数绑定到按钮,并且在初始化时不调用它。

button= Button(mainWindow, text='Click', command=doNothing)

如果需要传递参数,则需要使用lambda绕过调用:

button= Button(mainWindow, text='Click', command= lambda: doNothing(barVar))

答案 2 :(得分:-1)

我想我找到了解决方法。

在每个进度之后只需添加mainWindow.update()。所以最终的代码将是:

def doNothing():
  sleep(0.5)
  barVar.set(10)
  mainWindow.update()
  sleep(0.5)
  barVar.set(20)
  mainWindow.update()
  sleep(0.5)
  barVar.set(30)
  mainWindow.update()