Tcl/Tk - как заставить окно исчезать при нажатии кнопки OK, когда OK запускает симуляцию

У меня есть простое окно в Tcl/Tk, которое при нажатии кнопки OK запускает симуляцию. Я использую Линукс. Окно уничтожается, когда симуляция заканчивается. Проблема заключается в том, что окно остается открытым во время выполнения имитации. Я хочу, чтобы окно исчезло после нажатия кнопки «ОК».

Я пытался использовать wm withdraw .mywindow, но это делает область, в которой отображалось окно (содержащее кнопку «ОК»), белой.

Я нашел update во время поиска в Google, но говорят, что он вреден.


person Anand    schedule 20.04.2011    source источник
comment
Возможно, создать новый процесс/форк для симуляции? Не совсем ответ, но может быть как решение   -  person Adam Casey    schedule 21.04.2011
comment
Или начать тему. Много возможностей, каждая со своими плюсами и минусами.   -  person Donal Fellows    schedule 23.04.2011
comment
Update считается вредным, потому что очень легко попасть в беду из-за вложенных циклов событий, потребляющих много вашего стека C.   -  person Donal Fellows    schedule 23.04.2011


Ответы (1)


Если вы сделаете wm withdraw .mywindow, окно на самом деле не исчезнет до тех пор, пока не будет введен цикл событий, потому что именно цикл событий обрабатывает перерисовку экрана.

У вас есть несколько вариантов решения вашей проблемы. Например, вы можете вызвать обновление бездействующих задач. Это вариант update, который просто обрабатывает «бездействующие» задачи, такие как рисование экрана, но не такие задачи, как реагирование на кнопки и другие пользовательские события. Итак, первое решение:

wm withdraw .mywindow
update idletasks
run_simulation

Кстати, причина, по которой update вредна, заключается в том, что она, по сути, запускает новый цикл событий — еще один бесконечный цикл. Если во время этого цикла событий происходит событие, вызывающее повторный запуск того же кода, вы запускаете третий, четвертый и так далее. Как правило, вложенные бесконечные циклы никогда не бывают хорошими. Помните: tcl является однопоточным, поэтому эти циклы событий не выполняются параллельно.

Другое решение состоит в том, чтобы естественным образом войти в цикл обработки событий и запланировать запуск симуляции после обработки всех других событий. Для этого запустите симуляцию с помощью команды after. Использование after поместит событие в очередь событий. Когда цикл событий доберется до этого события, начнется ваша симуляция.

Например:

wm withdraw .mywindow
after idle run_simulation

Когда вышеприведенный код завершится — при условии, что он был вызван в результате события, такого как нажатие кнопки или клавиши — цикл событий будет повторно введен, все ожидающие события будут обработаны, затем будет запущена ваша команда run_simulation.

Кстати, если у вас есть графический интерфейс, который должен реагировать во время работы симуляции, прочтите Сохранить графический интерфейс. жив во время долгих вычислений на вики tcler. Там много чего можно прочитать, из-за чего проблема кажется сложнее, чем она есть на самом деле, но она не так сложна, как может показаться на первый взгляд.

person Bryan Oakley    schedule 22.04.2011
comment
+1 за очень хороший ответ, который охватывает ключевые основы и указывает, куда обратиться за дополнительной информацией. - person Donal Fellows; 23.04.2011