2015-08-21 2 views
1

Я использую проклятия в python2.7 для управления роботом. Я хотел бы управлять им, например. ключ 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) 

Это работает отлично, за исключением того, что я должен нажать ввести для ключа, чтобы быть признанным. Поэтому я могу нажать w несколько раз, и когда я нажимаю enter, робот выполняет именно то, что он должен делать, или в этом примере текст key w pressed появляется столько раз, сколько я его нажал. Но я хотел бы, чтобы это произошло немедленно, т. Е. Без нажатия клавиши ввода. Как это можно достичь?

+3

добавить 'curses.cbreak()' в вашу настройку. – meuh

+0

Это помогает, спасибо. Это также ломает мою оболочку, но я думаю, что смогу выяснить, как это исправить. Если вы поднимете этот комментарий к ответу, я его приму. – pfnuesel

ответ

1

добавьте curses.cbreak() к вашей настройке, а при очистке звоните curses.nocbreak(), чтобы восстановить терминал в пригодном для использования состоянии.

Вы можете сделать очистку, поймав ctrl-c в качестве исключения. Например:

try: 
    curses.cbreak() 
    while True: 
      key = shell.getch() 
      if key == 119: 
       print("key w pressed") 
      sleep(0.03) 
except KeyboardInterrupt: 
    curses.nocbreak() 
1

Учитывая, что ОП не использовать 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,

Программа всегда должны вызывать 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. 

Как уже отмечалось, cbreakraw и являются почти то же самое. Основное различие заключается в том, как программа будет реагировать на прерывания клавиатуры (например, ^C). Если вы используете ncurses, он устанавливает signal handlers, который (для SIGINT и SIGTERM) позвонит curses.endwin. Другие реализации проклятий не делают этого, и даже если ваш сценарий вызывает curses.endwin, он не уверен, что он будет работать по назначению (поскольку проклятия имеют тенденцию вызывать небезопасные функции ввода-вывода потока, которые нельзя надежно использовать в обработчике сигналов).

Смежные вопросы