Python Curses - Обнаружение клавиши Backspace

У меня проблемы с обнаружением клавиши Backspace с помощью модуля Curses. Всякий раз, когда я нажимаю клавишу Backspace, возвращаемым символом / строкой является '^?', Однако я не могу обнаружить его с помощью:

if str (key) == '^?':

Код ниже настроен для запуска

import curses

def main(win):
    win.nodelay(True)
    key = ''
    record = ''
    win.clear()
    win.addstr("Key:")
    win.addstr('\n\nRecord:')
    win.addstr(record)
    while True:
        try:
            key = win.getkey()

            if str(key) == '^?':
                # Attempt at detecting the Backspace key
                record = record[:-1]

            elif str(key) == '\n':
                # Attempt at detecting the Enter Key
                record = ''

            else:
                record += str(key)
            win.clear()
            win.addstr("Key:")
            win.addstr(str(key))
            win.addstr('\n\nRecord:')
            win.addstr(record)
            if key == os.linesep:
                break
        except Exception as e:
            # No input
            pass

curses.wrapper(main)
# CTRL+C to close the program

4 ответа

Согласно вашему уточняющему комментарию, Backspace в вашем терминале не является 'KEY_BACKSPACE' ни '\b' ('\x08').

Так как вы используете curses.wrapper(), который вызывает curses.initscr()это говорит о том, что что-то не так с вашим terminfo база данных (маловероятно) или конфигурация вашего терминала (более вероятно).

getkey() == 'KEY_BACKSPACE' или же getch() == curses.KEY_BACKSPACE должен работать на любой правильно настроенной системе, поэтому у вас, вероятно, будут проблемы и в других приложениях.

TERM Переменная окружения - это то, как тип терминала сообщается инструментам, которым требуется функциональность, выходящая за рамки базового телетайпа, поэтому, чтобы это исправить, начните с проверки того, что TERM Переменная окружения содержится в среде, в которой вы работаете с Python.

print(os.environ['TERM'])

Для быстрого взлома вы можете проверить все значения, которые были приняты.

if key in ('KEY_BACKSPACE', '\b', '\x7f'):

На моей машине под управлением Python 3.5.2 или 2.7.12 я получаю KEY_BACKSPACE отображается как клавиша, когда я нажимаю клавишу Backspace, и используя

if str(key) == 'KEY_BACKSPACE':

на месте

if str(key) == '^?':

приводит к тому, что клавиши Backspace отключают буквы record,

Я думаю, возможно, что в вашей системе вы получаете реальный символ возврата. В этом случае вы можете попробовать '\b' на месте '^?'Согласно документации, это escape-строка для символа возврата ASCII.

В MacOS попробуйте следующее:

          key = w.getch()
    if key == 127:
        print("You've pressed Backspace")

Глядя на исходный код , метод текстового поля Textbox.edit() возвращает только символ (например,curses.delch) когда либоcurses.ascii.BSилиcurses.ascii.BACKSPACEнажимаются. По крайней мере, в MacOSdeleteключ регистрируется какcurses.ascii.DEL.

Мы можем передать собственный метод validate(), чтобы перегрузить эту функциональность, например, возврат назад при DELETE, существование при ESCAPE и существование при RESIZE:

      import curses
import curses.textpad

def get_input(window):
    curses.curs_set(1)
    curses.set_escdelay(1)
    window.addstr(0, 0, "Enter some text:")
    input_box = curses.textpad.Textbox(curses.newwin(1, 40, 1, 0), insert_mode=True)
    
    def validate(ch):

            # exit input with the escape key
            escape = 27
            if ch == escape:
                ch = curses.ascii.BEL # Control-G
            
            # delete the character to the left of the cursor
            elif ch in (curses.KEY_BACKSPACE, curses.ascii.DEL):
                ch = curses.KEY_BACKSPACE
            
            # exit input to resize windows
            elif ch == curses.KEY_RESIZE:
                ch = curses.ascii.BEL # Control-G

            return ch
    
    input_box.edit(validate)
    curses.curs_set(0)
    curses.set_escdelay(1000)
    return input_box.gather().strip()


def main(window):
    curses.noecho()
    curses.cbreak()
    window.keypad(True)
    curses.curs_set(0)

    input_text = get_input(window)

    window.addstr(2, 0, f"You entered: {input_text}")
    window.refresh()
    window.getch()

if __name__ == "__main__":
    curses.wrapper(main)
Другие вопросы по тегам