Найти - Пользователи
Полная версия: Игра пинг понг
Начало » Python для новичков » Игра пинг понг
1
KImJon
Доброго времени суток друзья!!!
Помогите найти мою ошибку, а то я уже который день ломаю на дней голову.
Суть проблемы в следующем при закрытии программы PyCharm версий 2020.1,Выдает следующую ошибку:

C:\ForChildrens\Scripts\python.exe CUsers/mikki/PycharmProjects/ForChildrens/PaddleBall.py
Traceback (most recent call last):
File “C:\Users\mikki\PycharmProjects\ForChildrens\PaddleBall.py”, line 28, in <module>
ball.draw()
File “C:\Users\mikki\PycharmProjects\ForChildrens\PaddleBall.py”, line 10, in draw
self.canvas.move(self.id, 0, -1)
File “C:\Users\mikki\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py”, line 2917, in move
self.tk.call((self._w, ‘move’) + args)
_tkinter.TclError: invalid command name “.!canvas”

Process finished with exit code 1

Также выкладываю листинг данной программы.
 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):
        self.canvas.move(self.id, 0, -1)
tk = Tk()
tk.title('Игра')
tk.resizable(0, 0)
tk.wm_attributes('-topmost', 1)
canvas = Canvas(tk, width=500, height=400, bd=0, highlightthickness=0)
canvas.pack()
tk.update()
ball = Ball(canvas, 'red')
# def handler():
#     global run
#     run = False
# tk.protocol("WM_DELETE_ WINDOW", handler)
# run = True
while 1:
    ball.draw()
    tk.update_idletasks()
    tk.update()
    time.sleep(0.01)
tk.mainloop()
tk.destroy()
Заранее благодарю Вас друзья!!!
FishHook
в ГУИ программах нельзя слипать поток
https://realpython.com/python-sleep/#adding-a-python-sleep-call-with-guis
KImJon
Простите не понял при чем здесь задержка?
KImJon
можно по подробнее
FishHook
KImJon
Простите не понял при чем здесь задержка?
Задайтесь вопросом, как так получается, что в графическом приложении отдельные его части работают одновременно? В одной части окна у вас бегущая строка с каким-то текстом, в другом прогрессбар крутится, в третьем вы текст набираете, а при этом у вас еще курсор мыши по окну бегает и на все подряд можно нажимать и там еще звуки воспроизводятся, менюшки выпадают и пр. И что характерно, пока выпадает менюшка, прогрессбар продолжает крутиться, а курсор мигать. Сравните это с консольной программой. Вы выводите что-то на экран с помощью print, и пока этот вывод не закончится, программа не переходит на новую строку, она выполняется строго последовательно. Дело в том, что ГУИ программы устроены гораздо сложнее, чем это кажется. Вот этой строкой
 tk.mainloop()
вы запускаете цикл событий. Цикл событий запускается в отдельном от остальной программы потоке, он слушает события, приходящие в программу из вне, запускает отдельные компоненты, для обработки этих событий, позволяет компонентам общаться между собой, и вообще руководит этим оркестром, что в совокупности и дает вам ощущение того, что все работает одновременно. Это не так на самом деле, это невозможно. Каждый компонент работает монопольно какое-то небольшое время, совершая какую-то минимальную работу, потом цикл событий передает управление другому компоненту, и так далее. Это происходит много раз в секунду и создает иллюзию одновременности.
А вы взяли, и цикл событий остановили на 0.01 секунды, чем нарушили работу всей программы, вы рассинхронизировали все события. К чему это может привести предсказать нельзя. Вполне вероятно, что к вашей ошибке. Я на самом деле не знаю, является ли именно sleep вашей проблемой, но пока вы его не уберете из программы, дальше двигаться нельзя. Ну… ваша программа просто не может нормально работать.
rami
KImJon
Простите не понял при чем здесь задержка?
Задержка не при чём, проблема в вызове ball.draw() в цикле while 1: (ну и задержка там до кучи)

После закрытия окна этот цикл продолжает работать с уже не существующим окном, возникает ошибка.

Реализовать движение шарика нужно методом tk.after(). Это метод окна, после закрытия окна он также перестаёт “гонять шарик”.
 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):
        self.canvas.move(self.id, 0, -1)
 
 
def move_ball(obj):
    obj.draw()
    tk.after(10, lambda: move_ball(obj))
 
 
tk = Tk()
tk.title('Игра')
tk.resizable(0, 0)
tk.wm_attributes('-topmost', 1)
canvas = Canvas(tk, width=500, height=400, bd=0, highlightthickness=0)
canvas.pack()
tk.update()
ball = Ball(canvas, 'red')
 
move_ball(ball)
 
# def handler():
#     global run
#     run = False
# tk.protocol("WM_DELETE_ WINDOW", handler)
# run = True
 
# while 1:
#     ball.draw()
#     tk.update_idletasks()
#     tk.update()
#     time.sleep(0.01)
 
 
tk.mainloop()
# tk.destroy()
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB