为什么我的海龟程序不能正常关闭?

why doesnt't my turtle program close properly?

我用了海龟库(clock)的例子并扩展了它,所以即使打开其他程序它也保持在最前面。我希望它在有人点击时钟时关闭-window。大多数时候它工作正常,但有时会打开一个新的空海龟 window。如何在不弹出新 window 的情况下关闭它?

这是代码的关闭部分:

def main():
    tracer(False)
    setup()
    tracer(True)
    tick()
    wn.exitonclick()

这是整个程序:

import turtle as t
from datetime import datetime
import tkinter as Tkinter


def jump(distanz, winkel=0):
    penup()
    right(winkel)
    forward(distanz)
    left(winkel)
    pendown()

def hand(laenge, spitze):
    fd(laenge*1.15)
    rt(90)
    fd(spitze/2.0)
    lt(120)
    fd(spitze)
    lt(120)
    fd(spitze)
    lt(120)
    fd(spitze/2.0)

def make_hand_shape(name, laenge, spitze):
    reset()
    jump(-laenge*0.15)
    begin_poly()
    hand(laenge, spitze)
    end_poly()
    hand_form = get_poly()
    register_shape(name, hand_form)

def clockface(radius):
    reset()
    pensize(7)
    for i in range(60):
        jump(radius)
        if i % 5 == 0:
            fd(5)
            penup()
            fd(20)
            pendown()
            jump(-radius-25)
        else:
            dot(3)
            jump(-radius)
        rt(6)

def setup():
    global second_hand, minute_hand, hour_hand, writer, wn
    mode("logo")
    t.setup(width=150, height=150, startx=1920-150, starty=500)
    t.title("Clock")
    make_hand_shape("second_hand", 60, 15)
    make_hand_shape("minute_hand",  50, 15)
    make_hand_shape("hour_hand", 30, 15)
    clockface(60)
    second_hand = Turtle()
    second_hand.shape("second_hand")
    second_hand.color("gray20", "gray80")
    minute_hand = Turtle()
    minute_hand.shape("minute_hand")
    minute_hand.color("blue1", "red1")
    hour_hand = Turtle()
    hour_hand.shape("hour_hand")
    hour_hand.color("blue3", "red3")
    for hand in second_hand, minute_hand, hour_hand:
        hand.resizemode("user")
        hand.shapesize(1, 1, 3)
        hand.speed(0)
    ht()
    writer = Turtle()
    wn=Screen()
    wn.screensize(50, 50)
    wn.getcanvas()._root().overrideredirect(True)
    rootwindow = wn.getcanvas().winfo_toplevel()
    rootwindow.call('wm', 'attributes', '.', '-topmost', '1')
    #wn.exitonclick()
    #rootwindow.call('wm', 'attributes', '.', '-topmost', '0')
    #writer.mode("logo")
    writer.ht()
    writer.pu()
    writer.bk(85)

def wochentag(t):
    wochentag = ["Monday", "Tuesday", "Wednesday",
        "Thursday", "Friday", "Saturday", "Sunday"]
    return wochentag[t.weekday()]

def datum(z):
    monat = ["Jan.", "Feb.", "Mar.", "Apr.", "May", "June",
             "July", "Aug.", "Sep.", "Oct.", "Nov.", "Dec."]
    j = z.year
    m = monat[z.month - 1]
    t = z.day
    return "%s %d %d" % (m, t, j)

def tick():
    t = datetime.today()
    sekunde = t.second + t.microsecond*0.000001
    minute = t.minute + sekunde/60.0
    stunde = t.hour + minute/60.0
    try:
        tracer(False)  # Terminator can occur here
        writer.clear()
        writer.home()
        writer.forward(25)
        writer.write(wochentag(t),
                     align="center", font=("Courier", 11, "bold"))
        writer.back(60)
        writer.write(datum(t),
                     align="center", font=("Courier", 11, "bold"))
        writer.forward(85)
        tracer(True)
        second_hand.setheading(6*sekunde)  # or here
        minute_hand.setheading(6*minute)
        hour_hand.setheading(30*stunde)
        tracer(True)
        ontimer(tick, 100)
    except Terminator:
        pass  # turtledemo user pressed STOP

def main():
    tracer(False)
    setup()
    tracer(True)
    tick()
    wn.exitonclick()
    return "EVENTLOOP"
try:
    if __name__ == "__main__":
        mode("logo")
        msg = main()
        print(msg)
        mainloop()
except:
    pass

这是输出:

输出:

(正如所发布的那样,您的代码对我而言无法正确启动。)

我担心的是您同时拥有 mainloop()exitonclick()。它们执行相同的功能(exitonclick()onclick() 设置为 bye() 并调用 mainloop())并且应该只有其中之一。 (同上done()。)

下面我稍微修改了你的代码以简化它并使退出同步,而不是 exitonclick() 我设置了一个点击处理程序来设置一个全局变量,runningtick() 例行检查是否应再次调用 ontimer() 或执行 bye():

from turtle import Screen, Turtle
from datetime import datetime

FONT = ("Courier", 11, "bold")

def jump(distanz, winkel=0):
    turtle.penup()
    turtle.right(winkel)
    turtle.forward(distanz)
    turtle.left(winkel)
    turtle.pendown()

def hand(laenge, spitze):
    turtle.fd(laenge * 1.15)
    turtle.rt(90)
    turtle.fd(spitze / 2.0)
    turtle.lt(120)
    turtle.fd(spitze)
    turtle.lt(120)
    turtle.fd(spitze)
    turtle.lt(120)
    turtle.fd(spitze / 2.0)

def make_hand_shape(name, laenge, spitze):
    turtle.reset()
    turtle.hideturtle()
    jump(-laenge * 0.15)
    turtle.begin_poly()
    hand(laenge, spitze)
    turtle.end_poly()
    hand_form = turtle.get_poly()
    screen.register_shape(name, hand_form)

def clockface(radius):
    turtle.reset()
    turtle.hideturtle()
    turtle.pensize(7)

    for i in range(60):
        jump(radius)
        if i % 5 == 0:
            turtle.fd(5)
            turtle.penup()
            turtle.fd(20)
            turtle.pendown()
            jump(-radius - 25)
        else:
            turtle.dot(3)
            jump(-radius)

        turtle.rt(6)


def wochentag(t):
    wochentag = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]

    return wochentag[t.weekday()]

def datum(z):
    monat = ["Jan.", "Feb.", "Mar.", "Apr.", "May", "June", "July", "Aug.", "Sep.", "Oct.", "Nov.", "Dec."]

    j = z.year
    m = monat[z.month - 1]
    t = z.day

    return "%s %d %d" % (m, t, j)

def prepare_to_stop(x, y):
    global running

    running = False

def tick():
    t = datetime.today()

    sekunde = t.second + t.microsecond * 0.000001
    minute = t.minute + sekunde / 60.0
    stunde = t.hour + minute / 60.0

    screen.tracer(False)

    wochentag_writer.clear()
    wochentag_writer.write(wochentag(t), align="center", font=FONT)

    datum_writer.clear()
    datum_writer.write(datum(t), align="center", font=FONT)

    screen.tracer(True)

    second_hand.setheading(6 * sekunde)
    minute_hand.setheading(6 * minute)
    hour_hand.setheading(30 * stunde)

    if running:
        screen.ontimer(tick, 100)
    else:
        screen.bye()

screen = Screen()
screen.setup(width=170, height=170)
screen.mode("logo")
screen.title("Clock")

turtle = Turtle(visible=False)

screen.tracer(False)

make_hand_shape("second_hand", 60, 15)
make_hand_shape("minute_hand", 50, 15)
make_hand_shape("hour_hand", 30, 15)

clockface(60)

second_hand = Turtle()
second_hand.shape("second_hand")
second_hand.color("gray20", "gray80")

minute_hand = Turtle()
minute_hand.shape("minute_hand")
minute_hand.color("blue1", "red1")

hour_hand = Turtle()
hour_hand.shape("hour_hand")
hour_hand.color("blue3", "red3")

for hand in second_hand, minute_hand, hour_hand:
    hand.shapesize(1, 1, 3)
    hand.speed('fastest')

wochentag_writer = Turtle(visible=False)
wochentag_writer.penup()
wochentag_writer.forward(25)
wochentag_writer.write("", align="center", font=FONT)

datum_writer = Turtle(visible=False)
datum_writer.penup()
datum_writer.back(35)
datum_writer.write("", align="center", font=FONT)

screen.tracer(True)

screen.screensize(50, 50)

canvas = screen.getcanvas()
canvas._root().overrideredirect(True)
rootwindow = canvas.winfo_toplevel()
rootwindow.call('wm', 'attributes', '.', '-topmost', '1')

running = True

tick()
screen.onclick(prepare_to_stop)
screen.mainloop()

希望这些更改对您有用。