Код должен выводить красный мяч, но не выводит, а холст рисует

from tkinter import *
import random
import time


class Ball:
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = canvas.create_oval(10, 10, 25, 25, fill=color)
        self.canvas.move(self.id, 245, 100)

    def draw(self):
        pass


tk = Tk()
tk.title('Game')
tk.resizable(0, 0)
tk.wm_attributes('-topmost', 1)
canvas = Canvas(tk, width=500, height=400, bd=0, highlightthickness=0)
canvas.pack()
tk.update()
Tk.mainloop(canvas)
ball = Ball(canvas, 'red')
while 1:
    tk.update_idletasks()
    tk.update()
    time.sleep(0.01)

Код должен выводить красный мяч примерно по центру экрана, но красный мяч не выводит, а холст рисует. И при закрытии холста выдает ошибки:

Traceback (most recent call last):
  File "C:/Users/Misha/PycharmProjects/pythonGame1/GameStart.py", line 24, in <module>
    ball = Ball(canvas, 'red')
  File "C:/Users/Misha/PycharmProjects/pythonGame1/GameStart.py", line 9, in __init__
    self.id = canvas.create_oval(10, 10, 25, 25, fill=color)
  File "C:\Users\Misha\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 2793, in create_oval
    return self._create('oval', args, kw)
  File "C:\Users\Misha\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 2771, in _create
    return self.tk.getint(self.tk.call(
_tkinter.TclError: invalid command name ".!canvas"

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

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

Внутри метода mainloop и так выполняется бесконечный цикл, который постоянно вызывает метод update у окна. Этот метод выполняется все время, пока существует главное окно. Дополнительно свой бесконечный while True добавлять не нужно.

Ошибки появляются из-за того, что вы закрываете окно, все объекты на нем уничтожаются (в том числе Canvas), метод mainloop завершается, потом вы на несуществующем уже холсте пытаетесь вызвать create_oval (внутри класса Ball), в итоге получаете ошибку.

Вам нужно изменить вот этот кусок кода:

Tk.mainloop(canvas)
ball = Ball(canvas, 'red')
while 1:
    tk.update_idletasks()
    tk.update()
    time.sleep(0.01)

на такой:

ball = Ball(canvas, 'red')
tk.mainloop()
→ Ссылка