如何在python curses

时间:2017-06-01 23:48:32

标签: python-3.x curses

k = stdscr.getch()
if k == curses.KEY_UP:
    sys.stdout.write('KEY_UP')
elif k == curses.KEY_F1:
    sys.stdout.write('KEY_F1')
elif k == 113:
    break
else:
    pass

https://docs.python.org/2/library/curses.html

以上代码可用于检测' q'和arrow_up。但是,它不能用于检测F1。

问题>我可以使用python curses来检测特殊功能键吗?

[更新]

我的终端类型是xterm。

elif k == 269: # 'F5'
elif k == 270: # 'F6'
elif k == 271: # 'F7'
elif k == 272: # 'F8'
elif k == 273: # 'F9'
elif k == 27: # 'ESC'
    special_keys = [stdscr.getch(), stdscr.getch(), stdscr.getch(), stdscr.getch()]
    if special_keys == [91, 49, 49, 126]:
        sys.stdout.write('F1\n')
    if special_keys == [91, 49, 50, 126]:
        sys.stdout.write('F2\n')
    if special_keys == [91, 49, 51, 126]:
        sys.stdout.write('F3\n')
    if special_keys == [91, 49, 52, 126]:
        sys.stdout.write('F4\n')

根据@pbuck的建议,我测试了我的终端并列出了上面的结果。我不确定这个解决方案是否可移植。因为@pbuck只建议我在ESC之后使用接下来的两个键。对于我的情况,我必须提取接下来的四个键。

2 个答案:

答案 0 :(得分:0)

这样可以满足您的需求吗?

nKey = stdscr.getch()
sKeys = "%d" % nKey
if nKey == 27 :
    stdscr.nodelay(True)
    for n in range(0,10):
        nKey = stdscr.getch()
        if nKey == curses.ERR :
            break
        sKeys += " %d" % nKey
    stdscr.nodelay(False)
print ( "Key : %s" % sKeys )

它将显示如下:

[F1]    "27 91 49 49 126"
[F2]    "27 91 49 50 126"
[HOME]  "27 91 49 126"
[END]   "27 91 52 126"

这是一种清晰可见的结果的简便方法,但是对于稍后的if语句,使用list变量可能很容易。 按下[ESC]键会延迟。我发现此post是为了更改其行为。

-附加- 这样可以避免[ESC]的延迟,但会影响许多键代码和鼠标输入。

stdscr.keypad(False)

答案 1 :(得分:-1)

功能键由终端映射。例如,当您按F1键时,您的终端(可能)实际上正在发送类似Esc-OP的序列(如果您愿意,还可以发送^[OP)。所以,在stdscr.getch()上,如果它是Esc,请抓住接下来的几个字符以确定FKEY。

对特定转义序列进行硬编码并不是很好,但功能键序列依赖于接口(即您的xterm,控制台,终端窗口等)。对于* nix,这通常表示terminfo数据库。在某些界面上(比如我的emacs shell ),没有发送任何东西,因为终端驱动程序拦截了它!

您可以使用tputcat -A确定针对特定界面发送的 ,因为:

$ tput kp1 | cat -A
^[OP
$ tput kp10 | cat -A
^[[21~

但是,在我使用同一台计算机的情况下,使用控制台窗口会产生:

$ tput kp1 | cat -A
^[[21~
$ tput kp10 | cat -A
^[[[A