Тривиальная кнопка tkinter работает на Python 3.5, изначально не отвечает на Python 3.6, 3.7

#python #python-3.x #tkinter

#python #python-3.x #tkinter

Вопрос:

На Python 3.6 и 3.7 в macOS 10.12.6 a tkinter.Button изначально не реагирует на нажатия, но тот же код отлично работает на Python 3.5.

Если я запущу следующий скрипт:

 import tkinter as tk

root = tk.Tk()
button = tk.Button(root, text='Button')
button.pack()
root.mainloop()
  

затем на Python 3.6 и 3.7 появляется окно с одной кнопкой, как и ожидалось, она визуально не выглядит отключенной, но нажатие на нее не оказывает никакого эффекта.

Изменение размера окна или щелчок в другом месте внутри него не устраняет проблему. Однако, если я выведу другое приложение на передний план, а затем верну приложение Python обратно на передний план, все работает отлично, и тогда я не смогу заставить проблему появиться снова.

В Python 3.5 запуск тестового скрипта вызывает приложение, и кнопка немедленно реагирует на нажатия — как и ожидалось. Эксперименты не смогли воспроизвести какие-либо проблемы в 3.5. Скрипт также отлично работает в Python 2.7, если tkinter заменить на Tkinter .

Изменение pack layout manager на grid дало точно такие же результаты.

Я зашел так далеко, что перезагрузил компьютер без изменений.

Я почти на 100% уверен, что двоичные файлы и библиотеки Python 3.6 и Python 3.7 находятся в хорошем состоянии. По сути, это чистые установки, поскольку я полностью работаю в virtualenvs. И мое нетривиальное tkinter приложение работает идентично на Python 3.5, 3.6 и 3.7, за исключением этой одной проблемы.

Комментарии:

1. Хорошо, но в чем ваш вопрос? Какой ответ вы ищете?

2. измените свою строку на эту: button = tk.Button(root, text='Button', command=lambda:print('Hello!')) , это проверит, действительно ли кнопка работает

3. В вашем коде нет ничего плохого. Я думаю, что версия tkinter для OSX немного глючит.

4. @AndriiChumakov : Я только что отредактировал код для выполнения этого явного теста, и он работает и в крошечном тесте.

5. @Tom ты не первый, кто использует ее на Mac. Вот почему Брайан говорит, что она немного глючит на OSX. Потому что у других были проблемы. Интересно, может ли выполнение root.update_idletasks() прямо перед созданием кнопки устранить проблему. Я знаю, что в tkinter есть некоторые проблемы с фокусировкой, которые она исправит, поэтому стоит попробовать здесь.

Ответ №1:

У меня нет Mac для тестирования, но ваша проблема звучит очень похоже на проблему фокусировки, которая может возникнуть в Windows, когда вы открываете диалоговое окно файла до того, как mainloop завершит свой первый цикл. Проблема имеет те же симптомы, что и невозможность возврата фокуса к окну, пока вы не вызовете какое-либо другое приложение, а затем вернетесь к приложению tkinter, и тогда оно заработает.

Способ исправить проблему с фокусом — применить root.update_idletasks() до возникновения проблемы (Т. Е. прямо перед открытием диалогового окна файла) и в данном случае прямо перед вашей кнопкой.

Как указала OP, им пришлось добавить root.update_idletasks() до и после виджета, и я не уверен, почему это было исправлено здесь для OSX. Для тех, кто читает это с такой же проблемой на Mac, попробуйте этот вариант для обхода.

Комментарии:

1. Это устраняет проблему. Обратите внимание, что мне пришлось вызывать root.update_idletasks() дважды — один раз до и один раз после упаковки кнопки. Ни один вызов сам по себе не сработал!

2. @TomSwirly это может быть просто частью проблем с ошибками в OSX. У меня не было возможности по-настоящему поработать с python на Mac, поэтому я не могу точно сказать, почему. Я рад, что этот небольшой обходной маневр был здесь хитростью.

3. @TomSwirly вы сказали, что добавили обновление до и после pack() вы пробовали просто добавить его прямо перед определением кнопки?

4. На самом деле, я добавил эту строку во всех трех местах — перед созданием кнопки, перед упаковкой и после упаковки — и попробовал все восемь комбинаций, чтобы убедиться.

5. Мне нравится быть систематичным, это просто проще. Спасибо, что вытащили меня из затруднительного положения.