Insomnia
Insomnia

Reputation: 33

python-fail to get keypress in Tkinter

I'm simulating a 'Falldown' action when I press UpArrow, DownArrow, LeftArrow or RightArrow. I suppose it moves, but I got no response when I open Tkinter. It seems that it fails to get any keypress in sleep() time and Tk.after() time. How can I solve this problem?

Here is my code using Python-2.7 and Tkinter.

from Tkinter import *
import msvcrt,time
root=Tk()
c=Canvas(root,height=900,width=700)
c.pack()
p0=(450,450)
p1=(460,460)
a1=c.create_oval(p0,p1,fill='red')
def foo():
        if msvcrt.kbhit():
            key=msvcrt.getch()
            if key=='P':
                c.move(a1,0,5)
                a1.itemconfig(fill='yellow')
            elif key=='H':
                c.move(a1,0,-5)
                a1.itemconfig(fill='blue')
            elif key=='K':
                c.move(a1,-5,0)
                a1.itemconfig(fill='white')
            elif key=='M':
                c.move(a1,5,0)
                a1.itemconfig(fill='green')
            elif key =='\x1b':
                root.exit()
            c.after_cancel(m)
            c.pack()
            sleep(0.5)
            #root.update()
            foo()
        else:
            c.move(a1,0,2)
            m=c.after(1000,foo)
            #sleep(0.5)
            #root.update()
            c.pack()
foo()
root.mainloop()

Upvotes: 3

Views: 458

Answers (1)

falsetru
falsetru

Reputation: 368894

Instead of mixing Tkinter and msvcrt, it's better to use Tkinter's <Key> event to catch keypress.

Here's a modified version that use Key event:

from Tkinter import *

def foo(event):
    global m

    key = event.char
    if key.upper() == 'P':
        c.move(a1,0,5)
        c.itemconfig(a1, fill='yellow')
    elif key.upper() == 'H':
        c.move(a1,0,-5)
        c.itemconfig(a1, fill='blue')
    elif key.upper() == 'K':
        c.move(a1,-5,0)
        c.itemconfig(a1, fill='white')
    elif key.upper() == 'M':
        c.move(a1,5,0)
        c.itemconfig(a1, fill='green')
    elif key == '\x1b':
        root.destroy()
    c.after_cancel(m)
    m = c.after(1000, move)

def move():
    c.move(a1, 0, 2)
    m = c.after(1000, move)

root = Tk()
c = Canvas(root,height=900,width=700)
c.pack()
p0 = (450,450)
p1 = (460,460)
a1 = c.create_oval(p0,p1,fill='red')
m = root.after(1000, move)
root.bind('<Key>', foo)
root.mainloop()

Upvotes: 4

Related Questions