Я пытаюсь реализовать GUI, чтобы помочь некоторым коллегам в обработке изображений, но у меня возникла проблема с индикатором выполнения Tkinter (ttk), который продолжает отставать, пока я выполняю работу в другом потоке.
По сути, я хочу, чтобы индикатор выполнения работал в неопределенном режиме и подпрыгивал назад и вперед, как своего рода визуальное подтверждение того, что все еще продолжается (например, «рабочий» круг в windows).
Я настроил его следующим образом:
# Frame/root set up (etc.) above here...
pbv = IntVar()
progressBar = ttk.Progressbar(consoleFrame, orient="horizontal", length=100, variable=pbv, mode="indeterminate")
progressBar.grid(column=1, row=1, sticky=N)
progressBar.start()
root.mainloop()
, и он подпрыгивает, как и предполагалось, и прекрасно работает на основном потоке. Пока все хорошо.
Затем я инициализирую отдельный поток и запускаю очень вычислительную функцию.
externalFunctionThread = threading.Thread(target=expensiveFunctionThread, args=[foo])
externalFunctionThread.deamon = True
externalFunctionThread.start()
С некоторой функцией:
def expensiveFunctionThread(foo):
for i in range(a_few_iterations):
superDuperExpensiveFunction(i, foo)
# Note: Were I to comment this out and replace it with a time.sleep(n), the bar would progress normally
# Even a for loop that prints numbers up to some large integer would not cause lag
Для контекста, superDuperExaciousFunction - это вызов функции пирадиомики, которая генерирует множество текстурных функций из некоторого изображения.
В результате происходит значительное отставание панели, которая часто блокируется (не двигается), пока работает функция superDuperExoyFunction. двигаться после каждой итерации. Как только поток супердупер дорогой функции завершится, он вернется к нормальному состоянию.
Я смотрел другие потоки на этой плате ( Как подключить индикатор выполнения к функции? , Tkinter: Как использовать потоки, чтобы предотвратить «зависание» главного события l oop , ttk, индикатор зависания , et c.), Но ни один из них не помогает, поскольку это касается с прогресс-баром, замораживающимся в начале, в отличие от отставания в его обновлениях. Последний не работает (в том числе progressBar.update () / progressBar.update_idletasks () ничего не делает). Я боюсь, что это связано с тем, как Python обрабатывает потоки (поскольку в конечном итоге есть только 1 «реальный» поток, который может выполнять работу одновременно, и Python должен циклически обрабатывать, какой поток может работать ( GIL или что-то?)).
В любом случае, есть ли обходной путь для этого? Почему это может происходить?