4

以下は私の短いスクリプトです。これらの矢印キーを押したままにすると、左右上下に印刷されるようになっていますが、なぜ機能しないのかわかりません。

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()

この問題は、私が を使い始めたときに始まりましたroot.after()

4

1 に答える 1

6

Python では、関数は新しいスコープを作成します。変数が関数のスコープ内に見つからない場合、python は変数の外側 (モジュール/ファイル) スコープを探します。割り当てを使用して変数を現在のスコープに追加します。これはすべて次のことを意味します。

right = False
def func():
    right = True
func()
print (right)  #right is still False in the outer scope.

外部スコープで実際に変数を変更するには、そのようなことを明示的に行いたいことを python に伝える必要があります。

right = False
def func():
    global right
    right = True
func()
print (right)

これは機能しますが、プログラムの状態を変更しているため、良い習慣とは見なされません。の値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!

コードのもう少し「上品な」バージョンを次に示します。

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()
于 2013-01-30T01:41:57.550 に答える