Уведомления

Группа в Telegram: @pythonsu

#1 Сен. 22, 2021 10:23:04

KImJon
Зарегистрирован: 2021-08-01
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Игра пинг понг

Доброго времени суток друзья!!!
Помогите найти мою ошибку, а то я уже который день ломаю на дней голову.
Суть проблемы в следующем при закрытии программы 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()
Заранее благодарю Вас друзья!!!

Отредактировано KImJon (Сен. 22, 2021 11:14:18)

Офлайн

#2 Сен. 22, 2021 15:55:28

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Игра пинг понг

в ГУИ программах нельзя слипать поток
https://realpython.com/python-sleep/#adding-a-python-sleep-call-with-guis



Офлайн

#3 Сен. 23, 2021 04:39:52

KImJon
Зарегистрирован: 2021-08-01
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Игра пинг понг

Простите не понял при чем здесь задержка?

Офлайн

#4 Сен. 23, 2021 05:14:49

KImJon
Зарегистрирован: 2021-08-01
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Игра пинг понг

можно по подробнее

Офлайн

#5 Сен. 23, 2021 10:33:08

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Игра пинг понг

KImJon
Простите не понял при чем здесь задержка?
Задайтесь вопросом, как так получается, что в графическом приложении отдельные его части работают одновременно? В одной части окна у вас бегущая строка с каким-то текстом, в другом прогрессбар крутится, в третьем вы текст набираете, а при этом у вас еще курсор мыши по окну бегает и на все подряд можно нажимать и там еще звуки воспроизводятся, менюшки выпадают и пр. И что характерно, пока выпадает менюшка, прогрессбар продолжает крутиться, а курсор мигать. Сравните это с консольной программой. Вы выводите что-то на экран с помощью print, и пока этот вывод не закончится, программа не переходит на новую строку, она выполняется строго последовательно. Дело в том, что ГУИ программы устроены гораздо сложнее, чем это кажется. Вот этой строкой
 tk.mainloop()
вы запускаете цикл событий. Цикл событий запускается в отдельном от остальной программы потоке, он слушает события, приходящие в программу из вне, запускает отдельные компоненты, для обработки этих событий, позволяет компонентам общаться между собой, и вообще руководит этим оркестром, что в совокупности и дает вам ощущение того, что все работает одновременно. Это не так на самом деле, это невозможно. Каждый компонент работает монопольно какое-то небольшое время, совершая какую-то минимальную работу, потом цикл событий передает управление другому компоненту, и так далее. Это происходит много раз в секунду и создает иллюзию одновременности.
А вы взяли, и цикл событий остановили на 0.01 секунды, чем нарушили работу всей программы, вы рассинхронизировали все события. К чему это может привести предсказать нельзя. Вполне вероятно, что к вашей ошибке. Я на самом деле не знаю, является ли именно sleep вашей проблемой, но пока вы его не уберете из программы, дальше двигаться нельзя. Ну… ваша программа просто не может нормально работать.



Офлайн

#6 Сен. 23, 2021 10:58:15

rami
Зарегистрирован: 2018-01-08
Сообщения: 281
Репутация: +  72  -
Профиль   Отправить e-mail  

Игра пинг понг

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()

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version