_tkinter.TclError and Terminator issue

24 Views Asked by At

I've written the following code to be a screensaver, a little rough, but its a start. I can kind of get full screen but the issue I run into is when I close the app, I get the turtle terminator error. The whole point is to kill the app at any time in the process without throwing an error. Kind of like the old 3d pipes screensaver from the 90s. I have it convert ed to an '.scr' file, but I can only click the x or alt-f4 to terminate and it pops the error message. Can someone help, I feel like I'm right there.

import turtle as t

from turtle import Screen

import random

tim = t.Turtle()

tim.ht()

t.colormode(255)

tim.speed(6)

screen = Screen()

screenTk = screen.getcanvas().winfo_toplevel()

screenTk.attributes('-fullscreen', True)

color_list = [(54, 108, 149), (225, 201, 108), (134, 85, 58), (224, 141, 62),
              (197, 144, 171), (143, 180, 206), (137, 82, 106), (210, 90, 68), (188, 78, 122),
              (69, 101, 86), (132, 183, 132), (65, 156, 86), (137, 132, 74), (48, 155, 195), (183, 191, 202),
              (58, 47, 41), (47, 59, 96), (38, 44, 64), (106, 46, 54), (41, 55, 48), (12, 104, 95),
              (118, 125, 145), (182, 194, 199), (54, 45, 52)]

running = True

while running:

    tim.pu()

    tim.setpos(-825, -450)

    for i in range(7):

        for _ in range(12):

            tim.dot(100, random.choice(color_list))

            tim.fd(150)

        y = ((i + 1) * 150) – 450

        tim.setpos(-825, y)

    tim.clear()

screen.exitonclick()
1

There are 1 best solutions below

1
cdlane On

Your immediate problem appears to be this line:

y = ((i + 1) * 150) – 450

The subtraction sign isn't the correct character, it's some sort of Unicode look-alike not an actual - sign. But there's a bigger problem:

If this were corrected, and the program ran, you'd lock yourself out of your computer. The screen.exitonclick() is never reached, so you can't click your way out. Even if reached, you'd still be locked out as the click events have no opportunity to reach the event handler as you're constantly drawing.

This turns out to be a trickier problem than I first guessed. I've done a complete rework of your code, turning it inside out, so that the event handler is looped in for every dot. That way, when you click on the window, it will immediately quit and go away. (I defined my own exitonclick() functionality to avoid the error messages by being heartless.)

import sys
from turtle import Screen, Turtle
from random import choice

color_list = [
    (54, 108, 149), (225, 201, 108), (134, 85, 58), (224, 141, 62),
    (197, 144, 171), (143, 180, 206), (137, 82, 106), (210, 90, 68),
    (188, 78, 122), (69, 101, 86), (132, 183, 132), (65, 156, 86),
    (137, 132, 74), (48, 155, 195), (183, 191, 202), (58, 47, 41),
    (47, 59, 96), (38, 44, 64), (106, 46, 54), (41, 55, 48),
    (12, 104, 95), (118, 125, 145), (182, 194, 199), (54, 45, 52)
]

def draw_column(row=0, column=11):
    turtle.dot(100, choice(color_list))
    turtle.forward(150)

    if column > 0:
        screen.ontimer(lambda: draw_column(row, column - 1))
    else:
        screen.ontimer(lambda: draw_row(row + 1))

def draw_row(row=7):
    if row == 7:
        turtle.clear()
        turtle.setpos(-825, -450)
        screen.ontimer(draw_column)
    else:
        y = (row * 150) - 450
        turtle.setposition(-825, y)
        screen.ontimer(lambda: draw_column(row))

turtle = Turtle()
turtle.hideturtle()
turtle.penup()

screen = Screen()
screen.colormode(255)

window = screen.getcanvas().winfo_toplevel()
window.attributes('-fullscreen', True)

draw_row()

def exitHeartlessly(x, y):
    sys.exit(0)

screen.onclick(exitHeartlessly)

screen.mainloop()

In theory, screen.setup(width=1.0, height=1.0) should give you the same result as the attributes('-fullscreen', True) but in practice it doesn't so nice work finding a work-around.