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



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

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

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

谁能向我解释为什么我的箭头键的值似乎被存储为三元组?为什么会这样呢?所有平台都是如此吗?(我使用的是Debian Linux。)如果没有,我应该如何存储方向键的值?

这里的最终目标是,我正试图编写一个程序,需要正确识别方向键,并执行一个功能,取决于哪个方向键被按下。

我想我明白了。

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

然后我打开python控制台,插入我之前收到的三元组,试图找到它们的字符值。结果是,chr(27)给出了x1b, chr(91)给出了[,在65,66,67,68上调用chr分别返回了A,B,C,D。然后很明显:x1b是逃脱密码!

然后我注意到,一个箭头键,在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()

我使用Mac,我使用了以下代码,它运行良好:我的方向键的值为0,1,2,3(上,下,左,右):记住代码27的ESC键也很好。最好的问候!

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)

这里是一个小的解决方案的变体,它将同时读取正常字符和方向键。

import sys
import select
import tty
import termios
def isData():
    return select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], [])
old_settings = termios.tcgetattr(sys.stdin)
try:
    tty.setcbreak(sys.stdin.fileno())
 
    while 1:
        if isData():
            k = sys.stdin.read(1)
            if k == 'q':  
                break
            elif k=='x1b':
                kk = sys.stdin.read(2)
                if kk == 'OA':
                    print("up")
                elif kk=='OB':
                    print("down")
                elif kk=='OC':
                    print("right")
                elif kk=='OD':
                    print("left")
                else:
                    print("-->", kk.encode('unicode_escape'))
            else:
                print("char pressed: ", k)
                    
finally:
    termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)

相关内容

  • 没有找到相关文章

最新更新