TkInter:如何等待方法完成后的回调

2024-05-19 22:11:40 发布

您现在位置:Python中文网/ 问答频道 /正文

使用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

进度条会继续更新,因此我知道在打印后,加载在后台继续进行时被调用


Tags: runimportfordatetimedatetimedefload
1条回答
网友
1楼 · 发布于 2024-05-19 22:11:40

Question: the progress bar doesn't update - the window freezes until all functions have completed

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


Note:
You see a RuntimeError: main thread is not in main loop
if you .destroy() the App() window while the Thread is running!

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

Output:

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进行测试

相关问题 更多 >