#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. Мне нравится быть систематичным, это просто проще. Спасибо, что вытащили меня из затруднительного положения.