在Python中查找箭头键的值:为什么它们是三元组?

时间:2021-12-21 17:23:32

I am trying to find the values that my local system assigns to the arrow keys, specifically in Python. I am using the following script to do this:

我试图找到我的本地系统分配给箭头键的值,特别是在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()

Then I ran the script, and hit UP DOWN RIGHT LEFT, which gave me this output:

然后我运行了脚本,然后点击向上右下方,这给了我输出:

$ 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

This is anomalous because it suggests that the arrow keys are registered as some form of triple (27-91-6x) on my system, as each press of an arrow key takes up three instances of get(). By comparison, pressing a,b,c and CTRL-C gives:

这是异常的,因为它表明箭头键在我的系统上被注册为某种形式的三元组(27-91-6x),因为每次按箭头键都会占用三个get()实例。相比之下,按a,b,c和CTRL-C会给出:

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

Can anyone explain to me why the values of my arrow-keys seem to be stored as triples? Why is this is so? Is this the same across all platforms? (I'm using Debian Linux.) If not, how should I go about storing the values of the arrow-keys?

任何人都可以向我解释为什么我的箭头键的值似乎存储为三元组?为什么会这样?所有平台都是一样的吗? (我正在使用Debian Linux。)如果没有,我应该如何存储箭头键的值?

The end goal here is in that I'm trying to write a program which needs to correctly recognize arrow-keys and perform a function depending on which arrow-key was pressed.

这里的最终目标是我正在尝试编写一个程序,该程序需要正确识别箭头键并根据按下的箭头键执行功能。

2 个解决方案

#1


27  

I think I figured it out.

我想我想通了。

I learned from here that each arrow key is represented by a unique ANSI escape code. Then I learned that the ANSI escape codes vary by system and application: in my terminal, hitting cat and pressing the up-arrow gives ^[[A, in C it seems to be \033[A, etc. The latter part, the [A, remains the same, but the code for the preceding Escape can be in hex(beginning with an x), octal (beginning with a 0), or decimal(no lead in number).

我从这里了解到,每个箭头键都由唯一的ANSI转义码表示。然后我了解到ANSI转义代码因系统和应用而异:在我的终端中,按下猫并按向上箭头给出^ [[A,在C中它似乎是\ 033 [A,等等。后一部分, [A,保持不变,但前面Escape的代码可以是十六进制(以x开头),八进制(以0开头)或十进制(无数字中的引号)。

Then I opened the python console, and plugged in the triples I had previously received, trying to find their character values. As it turned out, chr(27) gave \x1b, chr(91) gave [, and calling chr on 65,66,67,68 returned A,B,C,D respectively. Then it was clear: \x1b was the escape-code!

然后我打开了python控制台,插入了之前收到的三元组,试图找到他们的角色值。事实证明,chr(27)给出了\ x1b,chr(91)给出了[,并且在65,66,67,68上调用chr分别返回A,B,C,D。然后很清楚:\ x1b是转义码!

Then I noted that an arrow key, in ANSI represented as a triple, is of course represented as three characters, so I needed to amend my code so as to read in three characters at a time. Here is the result:

然后我注意到一个ANSI表示为三元组的箭头键当然表示为三个字符,因此我需要修改我的代码以便一次读取三个字符。结果如下:

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

#2


3  

I am using Mac and I used the following code and it worked well: I got the values for my arrow keys as 0,1,2,3 (Up, Down, Left, Right): Always good to remember code 27 for ESC key too. Best regards!

我使用的是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)

#1


27  

I think I figured it out.

我想我想通了。

I learned from here that each arrow key is represented by a unique ANSI escape code. Then I learned that the ANSI escape codes vary by system and application: in my terminal, hitting cat and pressing the up-arrow gives ^[[A, in C it seems to be \033[A, etc. The latter part, the [A, remains the same, but the code for the preceding Escape can be in hex(beginning with an x), octal (beginning with a 0), or decimal(no lead in number).

我从这里了解到,每个箭头键都由唯一的ANSI转义码表示。然后我了解到ANSI转义代码因系统和应用而异:在我的终端中,按下猫并按向上箭头给出^ [[A,在C中它似乎是\ 033 [A,等等。后一部分, [A,保持不变,但前面Escape的代码可以是十六进制(以x开头),八进制(以0开头)或十进制(无数字中的引号)。

Then I opened the python console, and plugged in the triples I had previously received, trying to find their character values. As it turned out, chr(27) gave \x1b, chr(91) gave [, and calling chr on 65,66,67,68 returned A,B,C,D respectively. Then it was clear: \x1b was the escape-code!

然后我打开了python控制台,插入了之前收到的三元组,试图找到他们的角色值。事实证明,chr(27)给出了\ x1b,chr(91)给出了[,并且在65,66,67,68上调用chr分别返回A,B,C,D。然后很清楚:\ x1b是转义码!

Then I noted that an arrow key, in ANSI represented as a triple, is of course represented as three characters, so I needed to amend my code so as to read in three characters at a time. Here is the result:

然后我注意到一个ANSI表示为三元组的箭头键当然表示为三个字符,因此我需要修改我的代码以便一次读取三个字符。结果如下:

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

#2


3  

I am using Mac and I used the following code and it worked well: I got the values for my arrow keys as 0,1,2,3 (Up, Down, Left, Right): Always good to remember code 27 for ESC key too. Best regards!

我使用的是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)