【问题标题】:Turtle: timer keeps blinking乌龟:计时器一直在闪烁
【发布时间】:2020-02-20 01:14:36
【问题描述】:

我有一些计时器代码:

from turtle import Screen, Turtle, bgcolor

# --- functions ---

def delSec(string):
    if len(string) == 1:
        return "0" + string
    else:
        return string

def tick():
    global milisecs, ticking


    turtle.clear()

    if milisecs < 0:
        turtle.write("TIMER DONE", align='center', font=FONT)
        ticking = False
        return
    else:
        turtle.write(delSec(str(milisecs//(60*60*10)))+":"+delSec(str((milisecs%(60*60*10))//(60*10)))+":"+delSec(str((milisecs%(60*10))//10))+":"+str(milisecs%10), align='center', font=FONT)
##        turtle.write(delSec(str(milisecs//(60*60)))+":"+delSec(str((milisecs%(60*60))//(60)))+":"+delSec(str((milisecs%(60))//1)), align='center', font=FONT)
        if not paused:
              milisecs -= 1

    screen.ontimer(tick, 100)

def reset():
    global milisecs, ticking, key_reset, key_pause, key_both
    #global paused

    print("reset")

    screen.onkey(None, key_reset)  # Disable event handler inside handler
    screen.onkey(None, key_pause)  # Disable event handler inside handler
    screen.onkey(None, key_both)

    milisecs = sum(time*10)

    if not ticking:
        ticking = True
        tick()

    #paused = False

    screen.onkey(reset, key_reset)  # Reenable event handler
    screen.onkey(pause, key_pause)  # Reenable event handler
    screen.onkey(both, key_both)

def both():
    reset()
    pause()

def pause():
    global paused

    print("pause/unpause")

    paused = not paused

# --- main ---

bgcolor('darkblue')
FONT = ("Arial", 60, "normal")

strings = input("Please enter the time: ").strip().split(' ')

time = [60 ** (len(strings) - index - 1) * int(unit) for index, unit in enumerate(strings)]

milisecs = -1
ticking = False
paused = False
key_reset = "r"
key_pause = "p"
key_both = "b"

screen = Screen()

turtle = Turtle()
turtle.hideturtle()
turtle.color('white')

reset()

screen.listen()
screen.mainloop()

因为它每 10 秒变化一次,所以它一直在闪烁。这有点烦人,因为如果我在使用此计时器时尝试做某事,那么它会变得非常烦人。有什么方法可以使这个平滑而不是当前不断闪烁?谢谢! (我目前已将其设置为显示时间高达 10 分之一秒,我希望保持这种状态)


编辑:如果您想更改代码,请随意这样做,如果您保持当前功能相同,我会很高兴,所以不要这样做,以免其他东西不再起作用。谢谢!

【问题讨论】:

  • turtle.speed(0) 可能会阻止在清除屏幕和重绘更新的计时器之间更新显示。
  • 闪烁仍在发生。我想也许有些计算用完了一些时间。我愿意接受稍微不同的编码方法......
  • 你真的打算在你的程序中使用海龟的图形功能吗?改变屏幕上现有的东西并不适合海龟图形范式。如果您愿意切换到不同的方法,那么有许多选项可以轻松完成此类事情。 (turtle 所基于的 tkinter 库就是其中之一)。
  • 我不介意我使用什么方法,但我在选择解决问题的方法时非常缺乏经验。只要最终结果是一样的,或者在这种情况下更好,因为我现在的结果不是我想要的,我很高兴。我唯一的限制是我想使用 Python。

标签: python turtle-graphics


【解决方案1】:

我已经通过引入tracer()update() 屏幕方法对您(实际上是我们的)代码进行了最低限度的更改,以消除闪烁。这告诉海龟我们最清楚何时(手动)更新屏幕并自动停止更新:

from turtle import Screen, Turtle

# --- constants ---

FONT = ("Arial", 60, "normal")

KEY_RESET = "r"
KEY_PAUSE = "p"
KEY_BOTH = "b"

# --- functions ---

def delSec(string):
    if len(string) == 1:
        return "0" + string

    return string

def tick():
    global milisecs, ticking

    turtle.clear()

    if milisecs < 0:
        turtle.write("TIMER DONE", align='center', font=FONT)
        screen.update()
        ticking = False
        return

    turtle.write( \
        delSec(str(milisecs // (60*60*10))) + ":" + \
        delSec(str((milisecs % (60*60*10)) // (60*10))) + ":" + \
        delSec(str((milisecs % (60*10)) // 10)) + "." + \
        str(milisecs % 10), align='center', font=FONT)

    screen.update()

    if not paused:
        milisecs -= 1

    screen.ontimer(tick, 100)

def reset():
    global milisecs, ticking

    print("reset")

    screen.onkey(None, KEY_RESET)  # Disable event handler inside handler
    screen.onkey(None, KEY_PAUSE)  # Disable event handler inside handler
    screen.onkey(None, KEY_BOTH)

    milisecs = sum(time*10)

    if not ticking:
        ticking = True
        tick()

    screen.onkey(reset, KEY_RESET)  # Reenable event handler
    screen.onkey(pause, KEY_PAUSE)  # Reenable event handler
    screen.onkey(both, KEY_BOTH)

def both():
    reset()
    pause()

def pause():
    global paused

    print("pause/unpause")

    paused = not paused

# --- main ---

strings = input("Please enter the time: ").strip().split(' ')

time = [60 ** (len(strings) - index - 1) * int(unit) for index, unit in enumerate(strings)]

milisecs = -1
ticking = False
paused = False

screen = Screen()
screen.bgcolor('darkblue')
screen.tracer(False)

turtle = Turtle()
turtle.hideturtle()
turtle.color('white')

reset()

screen.listen()
screen.mainloop()

我还对代码进行了一些小的调整,并将十分之一秒的演示文稿从 "45:7" 更改为更标准化的 "45.7"。按您认为合适的方式还原。

【讨论】:

    猜你喜欢
    • 2018-01-25
    • 1970-01-01
    • 2017-08-09
    • 1970-01-01
    • 2023-03-28
    • 2021-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多