Пытаюсь сделать скачущий круг в питоне через Tkinter

Код:

from tkinter import *

root = Tk()
root["bg"] = "white"
root.title("лололо")
root.geometry("500x500")


canvas = Canvas(root, height = 500,width = 500)
canvas.pack()
WIDTH = HEIGHT = 500

ball = canvas.create_oval(225, 225, 275, 275, fill="black" )

xspeed = yspeed = 2

frame = Frame(root, width=500, height=500)
frame.pack()
frame.place(anchor='center', relx=0.5, rely=0.5)

label = Label(frame,image=ball)
label.pack()

def moveBall():

    global xspeed, yspeed

    canvas.move(canvas, xspeed, yspeed)

    (leftPos, topPos, rightPos, bottomPos) = canvas.coords(ball)

    if leftPos <= 0 or rightPos >= WIDTH:
        xspeed = -xspeed
    if topPos <= 0 or bottomPos >= HEIGHT:
        yspeed = -yspeed

    ball.after(30, moveBall)


canvas.after(30, moveBall)

root.mainloop()

Получаю ошибку: _tkinter.TclError: image "1" doesn't exist


Ответы (1 шт):

Автор решения: Amgarak

Начнём с того, что canvas.create_oval создаёт не изображение, а объект на холсте самого canvas. По этому ball, нельзя использовать как изображение для Label.

К тому же, для анимации Label не нужен. Можно просто использовать canvas.move(ball, ..), чтобы двигать только мяч.

У объекта ball нету метода .after(..) -> root.after(30, moveBall)

Исправим:

from tkinter import *

root = Tk()
root["bg"] = "white"
root.title("Скачущий мяч")
root.geometry("500x500")


canvas = Canvas(root, height=500, width=500, bg="white")
canvas.pack()
WIDTH = HEIGHT = 500

ball = canvas.create_oval(225, 225, 275, 275, fill="black")
xspeed = yspeed = 2

def moveBall():
    global xspeed, yspeed

    canvas.move(ball, xspeed, yspeed)
    leftPos, topPos, rightPos, bottomPos = canvas.coords(ball)

    if leftPos <= 0 or rightPos >= WIDTH:
        xspeed = -xspeed
    if topPos <= 0 or bottomPos >= HEIGHT:
        yspeed = -yspeed

    root.after(30, moveBall)


moveBall()
root.mainloop()

введите сюда описание изображения

→ Ссылка