更新时间:2022-10-19 07:43:55
问题:进度条不更新 - 窗口冻结,直到所有功能完成
使用线程
来防止主循环
冻结.
您的函数 - SomeFunction
、SecondFunction
- 也可能在 global
命名空间中.
然后你必须通过 self.pbar
作为参数,例如SomeFunction(pbar): ... f(self.pbar)
.
注意:
你看到一个 RuntimeError: main thread is not in main loop
如果.destroy()
App()
窗口,而Thread
正在运行!
导入 tkinter 作为 tk进口螺纹类应用程序(tk.Tk):def __init__(self):super().__init__()btn = tk.Button(self, text='Run',命令=lambda :threading.Thread(target=self.Load).start())btn.grid(row=0, column=0)self.pbar = ttk.Progressbar(self,maximum=2 *(5 * 5), mode='确定')self.pbar.grid(row=1, column=0)def SomeFunction(self):对于范围内的 num(5):print('SomeFunction({})'.format(num))self.pbar['value'] += 5时间.睡眠(1)返回编号def SecondFunction(self):对于范围内的 num(5):print('SecondFunction({})'.format(num))self.pbar['value'] += 5时间.睡眠(1)返回编号def 加载(自己):数字 = 0对于 [self.SomeFunction, self.SecondFunction] 中的 f:数字 += f()print('数字是:{}'.format(number))如果 __name__ == "__main__":应用程序().主循环()
输出:
SomeFunction(0)一些函数(1)一些函数(2)一些函数(3)一些函数(4)第二功能(0)第二功能(1)第二功能(2)第二功能(3)第二功能(4)数字是:8
使用 Python 测试:3.5*)无法使用 Python 2.7 进行测试
When using the Tkinter .after method, the code continues passed without waiting for the callback to complete.
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()
This example shows what is happening. The .after() calls the Load() function but doesn't wait for Load() to complete, it goes straight on to the next line.
I want i to print as 10 but because the .after() doesn't wait for Load() to finish it's additions, i prints as 0
The progress bar continues to update so I know that Load was called as it continues in the background after i is printed
Question: the progress bar doesn't update - the window freezes until all functions have completed
Use a Thread
to prevent main loop
from freezing.
Your functions - SomeFunction
, SecondFunction
- may also in global
namespace.
Then you have to pass self.pbar
as paramter, e.g. SomeFunction(pbar): ... f(self.pbar)
.
Note:
You see aRuntimeError: main thread is not in main loop
if you.destroy()
theApp()
window while theThread
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
Tested with Python: 3.5 *)Could not test with Python 2.7