简体   繁体   中英

Run multiple functions using turtle.screen.onkey() in Python

For the code:

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(reset, key_both)
    screen.onkey(pause, key_both)

def pause():
    global paused

    print("pause/unpause")

    paused = not paused

# --- main ---

bgcolor('dodgerblue')
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()

I want to both pause and reset the timer when I click the key "b". I tried doing this by running both functions reset and pause. However, as expected, it overwrites the first command of running the first function and only runs the second function when I click b (in this case, the function pause) I also tried the line screen.onkey(pause, reset, key_both) , but that created an error.

Could someone help me figure out how to run multiple functions? I can't find any parameter of .onkey() where it doesn't disable previous key-based functions. Please help!

Frustratingly, what you're asking for is built-in to the mouse event functions:

onclick(fun, btn=1, add=None)

where the add argument is used to indicate whether fun overrides the current setting or simply adds another function to execute in this circumstance. However, this wasn't included on the various onkey*() event handlers.

Below is what I consider a generic way to go about this:

from turtle import Screen

KEY_RESET = 'r'
KEY_PAUSE = 'p'
KEY_BOTH = 'b'

def reset():
    screen.onkey(None, KEY_RESET)  # Disable event handlers inside handler
    screen.onkey(None, KEY_BOTH)

    print("reset")

    screen.onkey(reset, KEY_RESET)  # Reenable event handlers
    screen.onkey(both, KEY_BOTH)

def pause():
    screen.onkey(None, KEY_PAUSE)  # Disable event handlers inside handler
    screen.onkey(None, KEY_BOTH)

    print("pause")

    screen.onkey(pause, KEY_PAUSE)  # Reenable event handlers
    screen.onkey(both, KEY_BOTH)

def both():
    reset()
    pause()

screen = Screen()

reset()

screen.listen()
screen.mainloop()

such that I can run multiple functions when I click b with just one line of code?

Yes, there's a hack we can do with lambda and a tuple but we shouldn't be thinking this way. "Just one line of code" should not be your goal at this point.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM