Skip to content Skip to sidebar Skip to footer

Python Returns An Error When I Try To Quit The Application Window

I was following a video for this little project but i encountered this error Traceback (most recent call last): File 'C:/Users/Dell/Desktop/Pygame/games/pong.py', line 92, in

Solution 1:

It looks like turtle uses tkinter. In Tk there's a method named protocol which you can use to control what happens when certain events happen, one of those being hitting the red 'X'.

In order to invoke that we need to get the root level window.

Placing

canvas = wn.getcanvas()
root = canvas.winfo_toplevel()

will set root as your root window.

From here you can use root.protocol("WM_DELETE_WINDOW", on_close) to invoke a function named on_close or whatever you want to name it.

Your function will probably look something like this.

def on_close():
    global running
    running = False

This will break you out of your loop and close your program.

Full Code.

import turtle

wn = turtle.Screen()

canvas = wn.getcanvas()
root = canvas.winfo_toplevel()

wn.title("Pong")
wn.bgcolor('black')
wn.setup(width=800, height=600)
wn.tracer(0)
#Score
score_a = 0
score_b = 0


#paddle A
paddle_a = turtle.Turtle()
paddle_a.speed(0)
paddle_a.shape("square")
paddle_a.color("white")
paddle_a.shapesize(stretch_wid=5, stretch_len = 1)
paddle_a.penup()
paddle_a.goto(-350,0)
#paddle B
paddle_b = turtle.Turtle()
paddle_b.speed(0)
paddle_b.shape("square")
paddle_b.color("white")
paddle_b.shapesize(stretch_wid=5, stretch_len = 1)
paddle_b.penup()
paddle_b.goto(350,0)


#Ball

ball = turtle.Turtle()
ball.speed(0)
ball.shape("circle")
ball.color("white")
ball.penup()
ball.goto(0,0)
ball.dx = 0.5
ball.dy = 0.5

#pen

pen = turtle.Turtle()
pen.speed(0)
pen.color("white")
pen.penup()
pen.hideturtle()
pen.goto(0,260)
pen.write("Player A: 0 Player B: 0", align="center", font=('Courier', 24, "normal"))

#Function
def paddle_a_up():
    y = paddle_a.ycor()
    y+=20
    paddle_a.sety(y)

def paddle_a_down():
    y = paddle_a.ycor()
    y-=20
    paddle_a.sety(y)

def paddle_b_up():
    y = paddle_b.ycor()
    y+=20
    paddle_b.sety(y)


def paddle_b_down():
    y = paddle_b.ycor()
    y-=20
    paddle_b.sety(y)
#Keyboard binding
wn.listen()
wn.onkeypress(paddle_a_up, "w")
wn.onkeypress(paddle_a_down, "s")
wn.onkeypress(paddle_b_up, "Up")
wn.onkeypress(paddle_b_down, "Down")

def on_close():
    global running
    running = False

root.protocol("WM_DELETE_WINDOW", on_close)

running = True
#main game loop
while running:
    wn.update()



    #move the ball
    ball.setx(ball.xcor()+ball.dx)
    ball.sety(ball.ycor()+ball.dy)

    #border
    if ball.ycor() > 280:
        ball.sety(280)
        ball.dy*=-1

    if ball.ycor() < -280:
        ball.sety(-280)
        ball.dy*=-1

    if ball.xcor() > 380:
        ball.goto(0,0)
        ball.dx*=-1
        score_a+=1
        pen.clear()
        pen.write(f"Player A: {score_a} Player B: {score_b}", align="center", font=('Courier', 24, "normal"))

    if ball.xcor() < -380:
        ball.goto(0,0)
        ball.dx*=-1
        score_b += 1
        pen.clear()
        pen.write(f"Player A: {score_a} Player B: {score_b}", align="center", font=('Courier', 24, "normal"))

    #colliosion
    if (ball.xcor() > 330 and ball.xcor() < 340) and (ball.ycor() < paddle_b.ycor() + 50 and ball.ycor() > paddle_b.ycor() -50):
        ball.setx(330)
        ball.dx*=-1
    if (ball.xcor() < -330 and ball.xcor() > -340) and (ball.ycor() < paddle_a.ycor() + 50 and ball.ycor() > paddle_a.ycor() -50):
        ball.setx(-330)
        ball.dx*=-1

Solution 2:

We can solve this problem from within turtle, no need to drop down to tkinter underpinnings. Generally, you need to play by the rules. Specifically, no while running: aka while True:. Turtle is an event-based environment and you're not letting events get handled properly and thus the error messages.

Instead of the while loop, we need an ontimer() event:

from turtle import Screen, Turtle

FONT = ('Courier', 24, 'normal')

# Score
score_a = 0
score_b = 0

# Function
def paddle_a_up():
    paddle_a.sety(paddle_a.ycor() + 20)

def paddle_a_down():
    paddle_a.sety(paddle_a.ycor() - 20)

def paddle_b_up():
    paddle_b.sety(paddle_b.ycor() + 20)

def paddle_b_down():
    paddle_b.sety(paddle_b.ycor() - 20)

def single_step():
    global score_a, score_b

    # move the ball
    ball.setposition(ball.xcor() + ball.dx, ball.ycor() + ball.dy)

    # border
    if ball.ycor() > 280:
        ball.sety(280)
        ball.dy *= -1
    elif ball.ycor() < -280:
        ball.sety(-280)
        ball.dy *= -1

    if ball.xcor() > 380:
        ball.goto(0, 0)
        ball.dx *= -1
        score_a += 1
        pen.clear()
        pen.write(f"Player A: {score_a} Player B: {score_b}", align='center', font=FONT)

    if ball.xcor() < -380:
        ball.goto(0, 0)
        ball.dx *= -1
        score_b += 1
        pen.clear()
        pen.write(f"Player A: {score_a} Player B: {score_b}", align='center', font=FONT)

    # collision
    if 330 < ball.xcor() < 340 and paddle_b.ycor() - 50 < ball.ycor() < paddle_b.ycor() + 50:
        ball.setx(330)
        ball.dx *= -1
    elif -340 < ball.xcor() < -330 and paddle_a.ycor() - 50 < ball.ycor() < paddle_a.ycor() + 50:
        ball.setx(-330)
        ball.dx *= -1

    screen.update()

    screen.ontimer(single_step)

screen = Screen()
screen.title('Pong')
screen.bgcolor('black')
screen.setup(width=800, height=600)
screen.tracer(0)

# paddle A
paddle_a = Turtle()
paddle_a.shape('square')
paddle_a.color('white')
paddle_a.shapesize(stretch_wid=5, stretch_len=1)
paddle_a.penup()
paddle_a.setx(-350)

# paddle B
paddle_b = Turtle()
paddle_b.shape('square')
paddle_b.color('white')
paddle_b.shapesize(stretch_wid=5, stretch_len=1)
paddle_b.penup()
paddle_b.setx(350)

# Ball
ball = Turtle()
ball.shape('circle')
ball.color('white')
ball.penup()

ball.dx = 1
ball.dy = 1

# pen
pen = Turtle()
pen.hideturtle()
pen.color('white')
pen.penup()

pen.sety(260)
pen.write("Player A: 0 Player B: 0", align='center', font=FONT)

# Keyboard binding
screen.onkeypress(paddle_a_up, 'w')
screen.onkeypress(paddle_a_down, 's')
screen.onkeypress(paddle_b_up, 'Up')
screen.onkeypress(paddle_b_down, 'Down')
screen.listen()

single_step()

screen.mainloop()

Now when you close the window, that event will be handled by the same mainloop event handler that's running your game.


Post a Comment for "Python Returns An Error When I Try To Quit The Application Window"