箭头键输入代码在tkinter中不起作用

Smi*_*mes 4 python tkinter

以下是我的简短剧本.当这些箭头键被按住时,它意味着向左和向上打印,但我不知道为什么它不起作用.

import Tkinter as tk

right = False
left = False
up = False

def keyPressed(event):
    if event.keysym == 'Escape':
        root.destroy()
    if event.keysym == 'Right':
        right = True
    if event.keysym == 'Left':
        left = True
    if event.keysym == 'Up':
        up = True

def keyReleased(event):
    if event.keysym == 'Right':
        right = False
    if event.keysym == 'Left':
        left = False
    if event.keysym == 'Up':
        up = False

def task():
    if right:
        print 'Right'
    if left:
        print 'Left'
    if up:
        print 'Forward'
    root.after(20,task)

root = tk.Tk()
print( "Press arrow key (Escape key to exit):" )

root.bind_all('<Key>', keyPressed)
root.bind_all('<KeyRelease>', keyReleased)
root.after(20,task)

root.withdraw()
root.mainloop()
Run Code Online (Sandbox Code Playgroud)

当我开始使用时,问题就开始了root.after().

mgi*_*son 6

在python中,函数创建一个新的范围.如果在函数的作用域内找不到变量,python会在变量的外部(模块/文件)范围内查找.您可以使用赋值将变量添加到当前范围中.这一切意味着:

right = False
def func():
    right = True
func()
print (right)  #right is still False in the outer scope.
Run Code Online (Sandbox Code Playgroud)

为了实际修改外部作用域中的变量,您需要告诉python您要明确地执行类似的操作:

right = False
def func():
    global right
    right = True
func()
print (right)
Run Code Online (Sandbox Code Playgroud)

这是有效的,但它不被认为是好的做法,因为你正在改变程序的状态.现在值right取决于你是否调用了一个有点令人不安的函数.

在函数调用之间共享数据的更好方法是使用.然后方法(绑定到类的实例的函数)可以更改该单个实例的状态,但是程序的其余部分可以继续,就像没有发生任何事情一样.

class Foo(object):
    def __init__(self):
        self.right = False
    def func(self):
        self.right = True

a = Foo() #calls __init__ implicitly
print(a.right)  #should be False -- We set this in __init__
a.func()  #change state of `a`
print(a.right)  #Now it's True!
Run Code Online (Sandbox Code Playgroud)

这是一个稍微更"优雅"的代码版本:

import Tkinter as tk

class App(object):
    def __init__(self):
        self.right = False
        self.left = False
        self.up = False

    def keyPressed(self,event):
        print "HERE"
        if event.keysym == 'Escape':
            root.destroy()
        elif event.keysym == 'Right':
            self.right = True
        elif event.keysym == 'Left':
            self.left = True
        elif event.keysym == 'Up':
            self.up = True

    def keyReleased(self,event):
        if event.keysym == 'Right':
            self.right = False
        elif event.keysym == 'Left':
            self.left = False
        elif event.keysym == 'Up':
            self.up = False

    def task(self):
        if self.right:
            print 'Right'
        elif self.left:
            print 'Left'
        elif self.up:
            print 'Forward'
        root.after(20,self.task)

application = App()
root = tk.Tk()
print( "Press arrow key (Escape key to exit):" )

root.bind_all('<Key>', application.keyPressed)
root.bind_all('<KeyRelease>', application.keyReleased)
root.after(20,application.task)

root.mainloop()
Run Code Online (Sandbox Code Playgroud)