Попытка исправить ошибку «RuntimeError: Вызов Tcl из другой квартиры» - PullRequest
0 голосов
/ 05 декабря 2018

Я исправляю приложение, в котором графический интерфейс зависает на длительные периоды, пока приложение выполняет настоящую работу.Я смог разморозить его, используя два потока (GUI / основной поток и поток "вычисления").Это дает мне то, что мне нужно, но, недопустимо, вышеуказанная ошибка отображается для конечного пользователя каждый раз, когда завершается вычислительный поток.

Каков правильный / канонический способисправить основную (неизбежную каламбур) причину этого сообщения? (Обратите внимание, что кладжи, такие как перенаправление stderr, недопустимы в результате поставки).

Я смотрел на многие, многие вопросы (100+) и несколько сайтов о способах устранения зависания.Я также прочитал много хитов, которые я получил, когда гуглил сообщение.В результате я сейчас немного растерялся.Куда мне идти отсюда?


Вот подробности того, что я сделал и попробовал.

«Расчет» перенесен в его собственный «огонь и забыл»"поток, заменив вызов" DoCalculation "следующими тремя строками:

from multiprocessing.dummy import Process        
DoCalculationProcess = Process( target = DoCalculation
DoCalculationProcess.start()

Отсутствие строки .join () является преднамеренным и предотвращает зависание графического интерфейса.

Поток вычисления не взаимодействует с графическим интерфейсом, кроме как для запуска Toplevel "Done" (в качестве дочернего элемента корневого / главного окна).Это происходит после завершения всех расчетов.

Приложение работает, как и ожидалось, за исключением доброкачественного (но тревожного) присутствия сообщения об ошибке, которое не появляется, пока не завершится расчетный поток.(Кстати, ошибка помечена в строке «Calculate.mainloop ()».)

Из нескольких вопросов (например, ответ Брайана Оуклиса на Tkinter генерирует и вызывает виртуальное событие между различными виджетами ) Я знаючто для устранения ошибки необходимо, чтобы:

  1. окно "Готово" отображалось потоком ГИП (основным), а
  2. поток вычисления должен отправлять событие "завершено"в основной поток (который затем отображает окно «Готово»).

Для этого я попытался использовать виртуальное событие 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?


Куда мне идти отсюда?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...