35

特にPythonで、ローカルシステムが矢印キーに割り当てる値を見つけようとしています。これを行うには、次のスクリプトを使用しています。

import sys,tty,termios
class _Getch:       
    def __call__(self):
            fd = sys.stdin.fileno()
            old_settings = termios.tcgetattr(fd)
            try:
                tty.setraw(sys.stdin.fileno())
                ch = sys.stdin.read(1)
            finally:
                termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
            return ch

def get():
    inkey = _Getch()
    while(1):
            k=inkey()
            if k!='':break
    print 'you pressed', ord(k)

def main():
    for i in range(0,25):
        get()

if __name__=='__main__':
    main()

次に、スクリプトを実行し、UP DOWN RIGHT LEFT を押すと、次の出力が得られました。

$ python getchar.py 
you pressed 27
you pressed 91
you pressed 65
you pressed 27
you pressed 91
you pressed 66
you pressed 27
you pressed 91
you pressed 67
you pressed 27
you pressed 91
you pressed 68

これは、矢印キーを押すたびに get() の 3 つのインスタンスが使用されるため、矢印キーが何らかの形式のトリプル (27-91-6x) としてシステムに登録されていることを示唆しているため、異常です。比較すると、a、b、c と CTRL-C を押すと、次のようになります。

you pressed 97
you pressed 98
you pressed 99
you pressed 3

矢印キーの値がトリプルとして保存されているように見える理由を誰かに説明できますか? どうしてこうなの?これはすべてのプラットフォームで同じですか? (私は Debian Linux を使用しています。) そうでない場合、矢印キーの値をどのように保存すればよいですか?

ここでの最終目標は、矢印キーを正しく認識し、押された矢印キーに応じて機能を実行する必要があるプログラムを作成しようとしていることです。

4

2 に答える 2

44

私はそれを理解したと思います。

ここから、各矢印キーが一意の ANSI エスケープ コードで表されることを学びました。次に、ANSI エスケープ コードがシステムとアプリケーションによって異なることを知りました。私の端末では、cat上向き矢印を押して押すと、先行するものは、16 進数 (x で始まる)、8 進数 (0 で始まる)、または 10 進数 (数字の先頭なし) にすることができます。^[[A\033[A[AEscape

次に、Python コンソールを開き、以前に受け取ったトリプルをプラグインして、それらの文字値を見つけようとしました。結局のところ、 Give 、Give 、および calling onがそれぞれ返されchr(27)ました。その後、それは明らかでした:エスケープコードでした!\x1bchr(91)[chr65,66,67,68A,B,C,D\x1b

次に、ANSI でトリプルとして表される矢印キーはもちろん 3 文字で表されることに気付きました。そのため、一度に 3 文字を読み取るようにコードを修正する必要がありました。結果は次のとおりです。

import sys,tty,termios
class _Getch:
    def __call__(self):
            fd = sys.stdin.fileno()
            old_settings = termios.tcgetattr(fd)
            try:
                tty.setraw(sys.stdin.fileno())
                ch = sys.stdin.read(3)
            finally:
                termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
            return ch

def get():
        inkey = _Getch()
        while(1):
                k=inkey()
                if k!='':break
        if k=='\x1b[A':
                print "up"
        elif k=='\x1b[B':
                print "down"
        elif k=='\x1b[C':
                print "right"
        elif k=='\x1b[D':
                print "left"
        else:
                print "not an arrow key!"

def main():
        for i in range(0,20):
                get()

if __name__=='__main__':
        main()
于 2014-03-14T07:16:16.907 に答える
7

私は Mac を使用しており、次のコードを使用しましたが、うまくいきました: 矢印キーの値を 0,1,2,3 (上、下、左、右) として取得しました: ESC キーのコード 27 を常に覚えておくことをお勧めしますそれも。よろしくお願いします!

while True:
    key = cv2.waitKey(1) & 0xFF

    # if the 'ESC' key is pressed, Quit
    if key == 27:
        quit()
    if key == 0:
        print "up"
    elif key == 1:
        print "down"
    elif key == 2:
        print "left"
    elif key == 3:
        print "right"
    # 255 is what the console returns when there is no key press...
    elif key != 255:
        print(key)
于 2016-09-08T20:00:17.593 に答える