Я исправляю приложение, в котором графический интерфейс зависает на длительные периоды, пока приложение выполняет настоящую работу.Я смог разморозить его, используя два потока (GUI / основной поток и поток "вычисления").Это дает мне то, что мне нужно, но, недопустимо, вышеуказанная ошибка отображается для конечного пользователя каждый раз, когда завершается вычислительный поток.
Каков правильный / канонический способисправить основную (неизбежную каламбур) причину этого сообщения? (Обратите внимание, что кладжи, такие как перенаправление stderr, недопустимы в результате поставки).
Я смотрел на многие, многие вопросы (100+) и несколько сайтов о способах устранения зависания.Я также прочитал много хитов, которые я получил, когда гуглил сообщение.В результате я сейчас немного растерялся.Куда мне идти отсюда?
Вот подробности того, что я сделал и попробовал.
«Расчет» перенесен в его собственный «огонь и забыл»"поток, заменив вызов" DoCalculation "следующими тремя строками:
from multiprocessing.dummy import Process
DoCalculationProcess = Process( target = DoCalculation
DoCalculationProcess.start()
Отсутствие строки .join () является преднамеренным и предотвращает зависание графического интерфейса.
Поток вычисления не взаимодействует с графическим интерфейсом, кроме как для запуска Toplevel "Done" (в качестве дочернего элемента корневого / главного окна).Это происходит после завершения всех расчетов.
Приложение работает, как и ожидалось, за исключением доброкачественного (но тревожного) присутствия сообщения об ошибке, которое не появляется, пока не завершится расчетный поток.(Кстати, ошибка помечена в строке «Calculate.mainloop ()».)
Из нескольких вопросов (например, ответ Брайана Оуклиса на Tkinter генерирует и вызывает виртуальное событие между различными виджетами ) Я знаючто для устранения ошибки необходимо, чтобы:
- окно "Готово" отображалось потоком ГИП (основным), а
- поток вычисления должен отправлять событие "завершено"в основной поток (который затем отображает окно «Готово»).
Для этого я попытался использовать виртуальное событие tkinter: (http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/virtual-events.html), добавив эти две строки сразу послесоздание корневого окна приложения:
import Finished # the "Done window, a Toplevel child of "root"
root.bind( '<<CalculationDone>>', Finished.FinishedWindow ( root, # then 3 other parameters )
и эта строка в конце (нового) раздела DoCalculation, перед самым выходом:
root.event_add( '<<CalculationDone>>' ) # needs to be an unconditional call
Код по-прежнему выдает ожидаемыйрезультаты, но это изменение не устранило причину сообщения.
Небольшая выборка связанных страниц, без частичного порядка, которая мне показалась полезной:
"RuntimeError:Вызов Tcl из другой квартиры "tkinter and threading
Ошибка tkinter на Python 3 (RuntimeError: Вызов Tcl из другой квартиры)
Как использоватьПоток в Python?
Как вы запускаете свой собственный код вместе с циклом событий Tkinter?
Куда мне идти отсюда?