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之后使用接下来的两个键。对于我的情况,我必须提取接下来的四个键。
答案 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 ),没有发送任何东西,因为终端驱动程序拦截了它!
您可以使用tput
和cat -A
确定针对特定界面发送的 ,因为:
$ tput kp1 | cat -A
^[OP
$ tput kp10 | cat -A
^[[21~
但是,在我使用同一台计算机的情况下,使用控制台窗口会产生:
$ tput kp1 | cat -A
^[[21~
$ tput kp10 | cat -A
^[[[A