我在python2.7中使用curses来控制机器人。我想引导它,例如w
键,告诉它它应该继续前进。这是我的代码,剥离了所有机器人控件:
import curses
from time import sleep
if __name__ == "__main__":
shell = curses.initscr()
shell.nodelay(True)
while True:
key = shell.getch()
if key == 119:
print("key w pressed")
sleep(0.03)
工作正常,但我必须按Enter键才能识别密钥。所以我可以按w
几次,当我按下回车键时,机器人完全按照它应该做的那样,或者在这个例子中,文本key w pressed
出现的次数与我一样多次压了它。但我希望这会立即发生,即无需按Enter键。如何实现这一目标?
答案 0 :(得分:1)
将RHEL
添加到您的设置中,清理时调用curses.cbreak()
将终端恢复到可用状态。
您可以通过将 ctrl-c 作为例外进行清理。例如:
curses.nocbreak()
答案 1 :(得分:1)
鉴于OP未使用window.keypad,调用curses.raw或curses.cbreak会给(几乎)相同的结果以允许脚本读取无缓冲的字符。
调用curses.endwin()
是一种更可靠的恢复方法。请记住,它是诅咒的包装。 curses 模拟 cbreak模式,将实际终端模式设置为 raw 。调用curses.nocbreak
对实际终端模式有 no 效果。
如果您致电nocbreak
进行清理而不是致电endwin
,则还需要解决其他问题(例如,请参阅Clean up ncurses mess in terminal after a crash),因为终端将处于原始模式(包括真实noecho
,这使得输入stty sane^M
很痛苦。
参考endwin
的文档,
程序应始终在退出或暂时退出curses模式之前调用 endwin 。这个例程
o restores tty modes,
o moves the cursor to the lower left-hand corner of the
screen and
o resets the terminal into the proper non-visual mode.
如上所述,cbreak
和raw
几乎相同。主要区别在于程序如何响应键盘中断(如^C
)。如果您正在使用ncurses,则会设置signal handlers(SIGINT
和SIGTERM
)会调用curses.endwin
。其他curses实现不执行此操作,即使您的脚本调用curses.endwin
,也不确定它是否会按预期工作(因为curses倾向于调用不安全的流I / O函数,这些函数无法在信号处理程序中可靠地使用)。
答案 2 :(得分:1)
现有答案正确,cbreak()
将关闭缓冲输入模式,这意味着getch()
将立即返回按键。
我建议使用curses.wrapper()
函数。在这种情况下,可以设置屏幕并进行缓冲。但是它还会捕获异常,并确保在应用程序退出时将终端返回到干净状态。阅读有关here
基于OPs代码的示例为:
import curses
from time import sleep
def program_loop(stdscr):
while True:
key = stdscr.getch()
if key == 119:
print("key w pressed\r")
sleep(0.03)
if __name__ == "__main__":
curses.wrapper(program_loop)