简体   繁体   中英

Key down event does not update variable inside while loop

I'm currently making an animation on the canvas using tkinter with python and running into some issues. The relevant portion of my code is below.

k = 0
dirX, dirY = 1, 0

def LeftButton(event):
    dirX = -abs(dirX)

c.bind("<Left>", LeftButton)

while 1:
    k %= 6
    #show one frame of animation and hide the rest
    c.itemconfig(pc[k], state=tk.NORMAL)
    c.itemconfig(pc[(k+1) % 6], state=tk.HIDDEN)
    c.itemconfig(pc[(k+2) % 6], state=tk.HIDDEN)
    c.itemconfig(pc[(k+3) % 6], state=tk.HIDDEN)
    c.itemconfig(pc[(k+4) % 6], state=tk.HIDDEN)
    c.itemconfig(pc[(k+5) % 6], state=tk.HIDDEN)
    #move all of the frames to the same location
    c.move(pc[k],dirX*5,dirY*5)
    c.move(pc[(k+1) % 6],dirX*5,dirY*5)
    c.move(pc[(k+2) % 6],dirX*5,dirY*5)
    c.move(pc[(k+3) % 6],dirX*5,dirY*5)
    c.move(pc[(k+4) % 6],dirX*5,dirY*5)
    c.move(pc[(k+5) % 6],dirX*5,dirY*5)
    
    k += 1
    #update the canvas
    c.update()
    time.sleep(.075)

Basically, pc is a numpy array of image objects on the canvas and at each index is a different image frame of the animation. Every .075 seconds it shows one frame and hides all of the others, and then increments the position of all of them. I am trying to build it so that when I press the left key, dirX becomes negative so my animation goes to the left. The animation is working fine, but the problem is that anything outside of the while loop is fixed, ie pressing a button does nothing. It may be that I am binding them wrong, but I binded it to a mouse click which I have done before and it still didn't work. Is there a better way to animate than a while loop?
One way I considered is instead of having while 1: I can put while not (code for keydown event): , but I don't know the code for a keydown event and I just want the variable dirX to update and then reinitiate the while loop, which is also problematic. What is the best way I can fix this? Thank you
Edit
I ran a test to see if LeftButton would print anything if the event was triggered, and it didn't. I think this means that while the code is running through the while loop it isn't checking or handling events.

In a GUI program, you already have the mainloop and any additional infinitely running loop will block the application.
Instead, try using the after function of tkinter.

def animation():
    # your itemconfig, move commands and
    # other animation logic.
    c.after(75, animation)

# start animation
animation()

This will tell tkinter to continue with the mainloop, and after 75ms, call the animation function again. after is often called from the root widget, but your canvas widget should work, too.

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