python - Tkinter 从函数中获取按键事件

标签 python tkinter

我有以下代码,

如果我按“左箭头键”,它只会打印move player to left 但是我需要一种功能,在该功能中,按下给定的箭头键可以使播放器朝给定的方向移动。

有没有一种方法可以在我的 move_dir 函数中检测按键事件
PS:对 python 相当陌生

import Tkinter as tk

move = 1
pos = -1


def move_dir():
    global move
    global pos
    while move ==1:
        if pos == 0:
            print 'move player to left'

        elif pos == 1:
            print 'move player to right'

        elif pos == -1:
            print 'stop moving!'

def kr(event):
    global move
    global pos
    global root
    if event.keysym == 'Right':
        move = 1
        pos = 0
        move_dir()
        print 'right ended'
    elif event.keysym == 'Left':
        move = 1
        pos = 1
        move_dir()
        print 'left ended'
    elif event.keysym == 'Space':
        move = 0
        move_dir()
    elif event.keysym == 'Escape':
        root.destroy()

root = tk.Tk()
print( "Press arrow key (Escape key to exit):" )
root.bind_all('<KeyRelease>', kr)
root.mainloop()

最佳答案

如果你想要动画,你应该使用after设置动画循环。动画循环看起来像这样:

def animate():
    <draw one frame of your animation>
    after(<delay>, animate)

你可以输入任何你想绘制框架的代码。在您的情况下,听起来您想向左或向右移动某些东西。 <delay>参数定义您的帧速率。例如,要获得 30FPS,您的延迟大约为 33 (1000ms/30)。唯一需要注意的重要事情是 <draw one from of your animation>需要运行得非常快(10 毫秒或更短)才能不阻塞 GUI。

对于您的特定问题,您可以设置一个变量来定义用户按下键时的方向,然后在用户释放键时取消设置该变量。您的事件处理程序和动画函数可能看起来像这样:

def animate():
    if direction is not None:
        print "move player to the ", direction
    after(33, animate)

def on_keypress(event):
    global direction
    if event.keysym == "Left":
        direction = "left"
    elif event.keysum == "right":
        direction = "right"

def on_keyrelease(event):
    global direction
    direction = None

看看它是如何工作的?当你按下一个键时,它定义了方向。然后,每 33 毫秒检查一次方向,如果定义了方向,则移动玩家。当用户释放按钮时,方向变得不确定并且移动停止。

将它们放在一起,并使用一个类来避免使用全局变量,它看起来像下面这样。这会在 Canvas 上创建一个球,您可以向左、向右、向上和向下移动:

import Tkinter as tk

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.direction = None

        self.canvas = tk.Canvas(width=400, height=400)
        self.canvas.pack(fill="both", expand=True)
        self.canvas.create_oval(190, 190, 210, 210, 
                                tags=("ball",),
                                outline="red", fill="red")

        self.canvas.bind("<Any-KeyPress>", self.on_press)
        self.canvas.bind("<Any-KeyRelease>", self.on_release)
        self.canvas.bind("<1>", lambda event: self.canvas.focus_set())

        self.animate()

    def on_press(self, event):
        delta = {
            "Right": (1,0),
            "Left": (-1, 0),
            "Up": (0,-1),
            "Down": (0,1)
        }
        self.direction = delta.get(event.keysym, None)

    def on_release(self, event):
        self.direction = None

    def animate(self):
        if self.direction is not None:
            self.canvas.move("ball", *self.direction)
        self.after(50, self.animate)

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(fill="both", expand=True)
    root.mainloop()

关于python - Tkinter 从函数中获取按键事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21440731/

相关文章:

python - 如何在 matplotlib python 中设置 x 轴值?

python - 如何使用 Tkinter 按钮跳出无限循环?

python - 使用包几何自动隐藏 Tkinter Canvas 滚动条

python - 结构错误 : unpack requires a string argument of length 4

python - 将 Cython 扩展类型方法传递给纯 C 函数

python - Django 通用多对多?

python - 如何向 pyqt 5 gui 添加滚动条?

python - 使用 tkinter 进行动态文本标记

python - 更多关于 tkinter optionmenu 第一个选项消失

python - 从与程序位于同一文件夹中的文件夹加载图像