代码之家  ›  专栏  ›  技术社区  ›  AhmedWas

Tkinter:调用函数时更新ProgressBar

  •  0
  • AhmedWas  · 技术社区  · 6 年前

    想象一下下面这个简单的例子:

    def donothing():
    睡眠(0.5)
    Barvar.集(10)
    睡眠(0.5)
    Barvar.集(20)
    睡眠(0.5)
    Barvar.集(30)
    
    主窗口=tk()
    barvar=双重评估())
    变量集(0)
    bar=progressbar(主窗口,长度=200,style='black.horizontal.tprogressbar',variable=barvar,mode='determinate')
    条形网格(行=1,列=0)
    button=button(主窗口,text='click',command=donothing)
    button.grid(行=0,列=0)
    mainWindow.mainLoop()。
    

    What I getwhen I run this,the progressbar already at 30%when clicking the button,no progress in front of me.如附件:

    我需要什么:I can see the progress in front of me(not hanging then猝然30%).

    更新: 我根据@bernhard answer更新了代码,但我仍然无法看到我前面的进度.。在等了1.5秒后突然跳了30%

    seocnd更新: 我只是在这里使用sleep来模拟一个需要时间的过程,比如通过ssh连接和获取一些信息。

    我得到什么当我运行这个时,当点击按钮时,进度条已经在30%,前面没有进度。如附件所示:

    enter image description here

    我需要的是:我能看到我面前的进展(不挂,突然30%)

    更新: 我根据@bernhard answer更新了代码,但我仍然在我面前看不到进展. 在等了1.5秒后突然跳了30%

    seocnd更新: 我只是在这里使用sleep来模拟一个需要时间的过程,比如通过ssh连接和获取一些信息。

    3 回复  |  直到 6 年前
        1
  •  1
  •   Mike - SMT    6 年前

    不使用 sleep() 在特金特。你问题的全部原因是 睡眠() 将冻结tkinter,直到其计数完成,所以您看到的是一个冻结的程序,当程序最终释放时,在下一次主循环更新时,它已经设置为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()
    
        2
  •  0
  •   Bernhard    6 年前

    因为您在初始化button时调用函数,所以需要释放命令中的“(barvar”)(barvar))。这样,您就可以将函数绑定到按钮,并且在初始化按钮时不调用它。

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

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

    button= Button(mainWindow, text='Click', command= lambda: doNothing(barVar))
    
        3
  •  -1
  •   AhmedWas    6 年前

    我想我找到了解决办法。

    只需添加 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()