Следующий код должен обновлять графический интерфейс пользователя и одновременно выполнять расчет. В этом случае self.after() не является решением, так как расчет будет продолжаться в течение длительного времени (а также должен быть time.sleep (n) в расчете, но это не должно останавливать работу графического интерфейса (т. Е. пользователь по-прежнему может настроить ползунки). Таким образом, это должно быть сделано с помощью нескольких потоков. следующий код, что я хотел бы предложить, но он не работает. Любые предложения, что я ошибалась?Tkinter с несколькими потоками
import Tkinter as tk
import ttk
import time
import threading
class GUI(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.pack()
self.i=0
self.var1 = tk.StringVar()
self.var2 = tk.StringVar()
self.var3 = tk.StringVar()
self.var4 = tk.StringVar()
self.var5 = tk.StringVar()
self.var6 = tk.StringVar()
self.var7 = tk.StringVar()
tk.Label(self, textvariable=self.var1,justify='left').pack()
tk.Label(self, textvariable=self.var2).pack()
tk.Label(self, textvariable=self.var3).pack()
tk.Label(self, textvariable=self.var4).pack()
tk.Label(self, textvariable=self.var5).pack()
tk.Label(self, textvariable=self.var6).pack()
tk.Label(self, textvariable=self.var7).pack()
p1 = tk.Scale(master, from_=1, to=20, orient=tk.HORIZONTAL).pack()
p2 = tk.Scale(master, from_=1, to=20, orient=tk.HORIZONTAL).pack()
p3 = tk.Scale(master, from_=1, to=20, orient=tk.HORIZONTAL).pack()
p4 = tk.Scale(master, from_=1, to=20, orient=tk.HORIZONTAL).pack()
p5 = tk.Scale(master, from_=1, to=20, orient=tk.HORIZONTAL).pack()
self.progress = ttk.Progressbar(self, orient="horizontal",length=100, mode="determinate")
self.progress.pack()
def calculation(self):
while True:
# complex calculations that last 30 minutes in total
self.i += 1
time.sleep(1)
max=1000
self.var1.set("Value1: "+str(self.i))
self.var2.set("Value2: "+str(self.i+100))
self.var3.set("Value3: "+str(self.i+100))
self.var4.set("Value4: "+str(self.i+100))
self.var5.set("Value5: "+str(self.i+100))
self.var6.set("Value6: "+str(self.i+100))
self.var7.set("Value7: "+str(self.i+100))
self.progress["value"] = int(round(self.i*100/max))
#self.update() # no need, will be automatic as mainloop() runs
#self.after(1, self.calculation) not necessary anymore as everything is in a main loop
app=GUI()
t1 = threading.Thread(target=app.calculation, args=[])
t2 = threading.Thread(target=app.mainloop, args=[])
t1.start()
t2.start()
t1.join()
t2.join()
print ("thread finished...exiting")
Несколько потоков не могут взаимодействовать с объектами Tkinter. Ваше утверждение о необходимости вызова 'time.sleep()' в вычислении является полной бессмыслицей. Хорошим способом безопасного многопоточности в приложении Tkinter является использование объектов (Queue) для передачи (передачи данных) из вспомогательных потоков в основной. Обычно 'self.after()' используется для планирования периодического извлечения данных, которые генерирует другой поток (ы). – martineau
Нет, это не полная глупость, мне нужна функция сна. Вышеприведенный пример - упрощение моей реальной проблемы, и в моей реальной проблеме есть несколько функций сна, которые необходимы (бот-покер, который играет сам по себе и должен убедиться, что программа имеет человеческий облик) – Nickpick
Если вам действительно нужно поставьте временную задержку в «вычислении», документы говорят, что вы можете использовать 'self.after()' вместо 'time.sleep()', но передавать только один аргумент значения времени. – martineau