Astro Wolfe
Astro Wolfe

Reputation: 23

TKinter: Move while key is pressed, stopped when not

I am trying to create a "smoother" movement with my ball. Basically, I want my program to detect when a key is press, and have it move the ball at a constant speed, and when the key is not pressed, to have it stop.

This is my code:

import time
import Tkinter
import math

root = Tkinter.Tk()

r = 10
x = 150
y = 150

canvas = Tkinter.Canvas(root, width=600, height=600, background='#FFFFFF')
canvas.grid(row=0, rowspan=2, column=1)

circle_item = canvas.create_oval(x - r, y - r, x + r, y + r,
                                 outline='#000000', fill='#00FFFF')
global leftInt
leftInt = 0


def leftMove(Event):
    global leftInt
    leftInt = 1
    gogo = 1
    if (gogo == 1):
        ballMove()
        gogo = 2


def leftStop(Event):
    global leftInt
    leftInt = 0
    print("im stop")


def rightMove(Event):
    canvas.move(circle_item, 5, 0)
    x1, y1, x2, y2 = canvas.coords(circle_item)


def upMove(Event):
    canvas.move(circle_item, 0, -5)
    x1, y1, x2, y2 = canvas.coords(circle_item)


def downMove(Event):
    canvas.move(circle_item, 0, 5)
    x1, y1, x2, y2 = canvas.coords(circle_item)


def ballMove():
    global leftInt
    while (leftInt == 1):
        print('im go')
        canvas.move(circle_item, -5, 0)
        x1, y1, x2, y2 = canvas.coords(circle_item)
        time.sleep(.1)


ballMove()

root.bind('<Left>', leftMove)
root.bind('<KeyRelease>', leftStop)
root.bind('<Right>', rightMove)
root.bind('<Up>', upMove)
root.bind('<Down>', downMove)

root.mainloop()

I was trying to create a while loop while it was pressed, then have the KeyRelease stop it. Why doesn't it stop? How can I fix this?

Upvotes: 0

Views: 1964

Answers (1)

user4171906
user4171906

Reputation:

Note that the OS's repeat rate and how it handles a key that is held down determines what happens, so it is likely that you will see both "im go" and "im stop" even though you are holding down the key continuously. Change ballMove() to use Tkinter's after method. You should not use time.sleep() in a GUI program as it can interrupt the GUI's infinite loop.

def ballMove():
    global leftInt
    if (leftInt == 1):
        x1, y1, x2, y2 = canvas.coords(circle_item)
        print('im go', x1)
        if x1 > 3:        ## keep it on the canvas
            canvas.move(circle_item, -5, 0)
            root.after(100, ballMove)

Upvotes: 2

Related Questions