RecursionError в macOS с движущимися объектами tkinter - PullRequest
1 голос
/ 17 октября 2019

Я учусь с помощью tkinter, и это связано с плавным движением фигур. Вот где я застрял.

Я получаю противоречивые ошибки рекурсии. Код работает без проблем в Windows 10, но на моем macOS он вылетает.

Кроме того, если время между рекурсиями составляет ≥ 17 миллисекунд, он просто перестает совершать ошибки и работает как задумано. Я упростил код, чтобы устранить одну проблему.

from tkinter import *
master = Tk()
canvas = Canvas(bg = "gray", width = 1000, height = 800)
canvas.pack()
cara = canvas.create_line(100,100,900,100, width = 5, fill = "red")

def moveCara():
    canvas.move(cara, 0,1)
    canvas.after(16, moveCara)  # Here is the time setting, change it to 17 and the thing
                                # does not crash.
    canvas.update()

moveCara()
mainloop()

Этот код вызывает сбой на моем MacBook:

RecursionError: maximum recursion depth exceeded during compilation

Однако, если яизмените время в canvas.after() на 17 или больше, все работает. почему это?

1 Ответ

0 голосов
/ 18 октября 2019

Проблема в следующей строке кода:

canvas.update()

Определенно не следует вызывать update внутри функции, вызываемой из обработчика события (а запуск функции через after считается событиемобработчик). Совершенно не нужно, чтобы ваша программа работала, и ее необходимо удалить.

В результате ваш вызов after добавляет некоторую работу, которую нужно выполнить mainloop через определенный промежуток времени. Когда вы звоните update, он выполняет эту работу, если прошло определенное время, иначе он может вообще ничего не делать.

Если ваш компьютер достаточно медленный, то к тому времени, когда вы позвоните update, наступит время для следующего кадра вашей анимации. Это вызывает повторный вызов moveCora через canvas.update() до того, как первый вызов вернет . И именно поэтому вы получаете ошибку рекурсии.

Мне не удалось воспроизвести проблему на моей машине на 16 мс, но я смог воспроизвести ее, когда перенес время на 5 мс. У вас должна быть машина, которой требуется более 16 мс для перемещения линии, а затем позвоните after. Когда я удаляю вызов на canvas.update(), я могу без проблем установить значение до 1 мс.

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