TkInter:如何等到方法完成后才进行回调

时间:2019-04-26 14:11:53

标签: python tkinter

使用Tkinter .after方法时,代码继续传递而无需等待回调完成。

import tkinter as tk
import tkinter.ttk as ttk
import time
from datetime import datetime

global i
i = 0
global j
j = 0

def SomeFunction():
    global i
    for num in range(10):
        i+=1
        x = barVar.get()
        barVar.set(x+5)
        histrun_mainWindow.update()
        time.sleep(2)

def SecondFunction():
    global j
    for num in range(10):
        j+=1
        x = barVar.get()
        barVar.set(x+5)
        histrun_mainWindow.update()
        time.sleep(2)

def Load(run_date):
    histrun_mainWindow.after(50, SomeFunction)
    histrun_mainWindow.after(50, SecondFunction)
    global i, j 
    print 'Number is :', i + j

histrun_mainWindow = tk.Tk()
run_date = datetime.today().date()
barVar = tk.DoubleVar()
barVar.set(0)
bar = ttk.Progressbar(histrun_mainWindow, length=200, style='black.Horizontal.TProgressbar', variable=barVar, mode='determinate')
bar.grid(row=1, column=0)
button= tk.Button(histrun_mainWindow, text='Run for this date ' + str(run_date), command=lambda:Load(run_date))
button.grid(row=0, column=0)
histrun_mainWindow.mainloop()

此示例显示了正在发生的事情。 .after()调用Load()函数,但不等待Load()完成,它直接进入下一行。

我希望我将其打印为10,但是由于.after()不等待Load()完成添加,所以我将打印为0

进度条继续更新,所以我知道在打印我后继续在后台调用Load

1 个答案:

答案 0 :(得分:0)

  

问题:进度条不会更新-窗口冻结,直到所有功能都完成

使用Thread防止main loop冻结
您的函数SomeFunctionSecondFunction-也可以在global命名空间中。
然后,您必须将self.pbar作为参数传递,例如SomeFunction(pbar): ... f(self.pbar)


  

注意
  您看到一个RuntimeError: main thread is not in main loop
  如果您在.destroy()运行时App() Thread窗口

import tkinter as tk
import threading

class App(tk.Tk):
    def __init__(self):
        super().__init__()
        btn = tk.Button(self, text='Run', 
                              command=lambda :threading.Thread(target=self.Load).start())
        btn.grid(row=0, column=0)
        self.pbar = ttk.Progressbar(self, maximum=2 *(5 * 5), mode='determinate')
        self.pbar.grid(row=1, column=0)

    def SomeFunction(self):
        for num in range(5):
            print('SomeFunction({})'.format(num))
            self.pbar['value'] += 5
            time.sleep(1)
        return num

    def SecondFunction(self):
        for num in range(5):
            print('SecondFunction({})'.format(num))
            self.pbar['value'] += 5
            time.sleep(1)
        return num

    def Load(self):
        number = 0
        for f in [self.SomeFunction, self.SecondFunction]:
            number += f()
        print('Number is :{}'.format(number))

if __name__ == "__main__":
    App().mainloop()
  

输出

SomeFunction(0)
SomeFunction(1)
SomeFunction(2)
SomeFunction(3)
SomeFunction(4)   
SecondFunction(0)
SecondFunction(1)
SecondFunction(2)
SecondFunction(3)
SecondFunction(4)
Number is :8

使用Python测试:3.5 *)无法在Python 2.7上进行测试