Некоторые урезанные коды, иллюстрирующие проблему, приведены ниже. Я поместил операторы печати в функцию, вызываемую как из обработчика событий, так и из кнопки, чтобы убедиться, что операторы печати работают должным образом. Trial_count просто помогает прочитать результаты. Нет необходимости иллюстрировать проблему.
import tkinter as tk
trial_count = 0
def print_data(caller):
global trial_count
trial_count += 1
print('---------- trial ' + str(trial_count) + ' called from ' + caller + ' ------------')
print('try canvas.winfo_width()', canvas.winfo_width())
print('try canvas.coords(box)', canvas.coords(box))
def destroy_root(event):
print_data('destroy_root')
def btn():
print_data('button')
root = tk.Tk()
root.bind('', destroy_root)
canvas = tk.Canvas(root)
canvas.pack()
box = canvas.create_rectangle(20, 20, 100, 50)
tk.Button(root, text='click to print', command=btn).pack()
root.mainloop()
Следует результат запуска сценария.
- Пробная версия 1 показывает результаты при нажатии кнопки. Canvas.winfo_width() и Canvas.coords(box) делают то, что я ожидал.
- Испытание 2 показывает результаты при первом запуске Destroy_root, когда я закрыл окно.
Canvas.winfo_width() завершается успешно, поэтому Canvas еще не уничтожен, но затем происходит сбой Canvas.coords(box). Я не понимаю, почему код не может получить координаты ящика, если Canvas все еще там? - Полагаю, триалы 3 и 4 означают, что событие запускалось снова и снова. Понятия не имею, почему?
try canvas.winfo_width() 290
try canvas.coords(box) [20.0, 20.0, 100.0, 50.0]
---------- trial 2 called from destroy_root ------------
try canvas.winfo_width() 290
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/tkinter/__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "/Users/stephenvandellen/PycharmProjects/Windows/destroy.py", line 12, in destroy_root
print_data('destroy_root')
File "/Users/stephenvandellen/PycharmProjects/Windows/destroy.py", line 9, in print_data
print('try canvas.coords(box)', canvas.coords(box))
^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/tkinter/__init__.py", line 2823, in coords
self.tk.call((self._w, 'coords') + args))]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_tkinter.TclError: invalid command name ".!canvas"
---------- trial 3 called from destroy_root ------------
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/tkinter/__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "/Users/stephenvandellen/PycharmProjects/Windows/destroy.py", line 12, in destroy_root
print_data('destroy_root')
File "/Users/stephenvandellen/PycharmProjects/Windows/destroy.py", line 8, in print_data
print('try canvas.winfo_width()', canvas.winfo_width())
^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/tkinter/__init__.py", line 1354, in winfo_width
self.tk.call('winfo', 'width', self._w))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_tkinter.TclError: bad window path name ".!canvas"
---------- trial 4 called from destroy_root ------------
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/tkinter/__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "/Users/stephenvandellen/PycharmProjects/Windows/destroy.py", line 12, in destroy_root
print_data('destroy_root')
File "/Users/stephenvandellen/PycharmProjects/Windows/destroy.py", line 8, in print_data
print('try canvas.winfo_width()', canvas.winfo_width())
^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/tkinter/__init__.py", line 1354, in winfo_width
self.tk.call('winfo', 'width', self._w))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_tkinter.TclError: bad window path name ".!canvas"
Подробнее здесь: https://stackoverflow.com/questions/785 ... -window-is