Туториал по Curses

Curses — это встроенный в Python модуль для отрисовки интерфейса в терминале. У модуля объемная документация, и этот краткий туториал поможет быстро разобраться в азах использования модуля.

Полную документацию можно найти здесь.

Старт приложения

Сразу приведём пример использования Curses. Он отрисует надпись «Hello, World», подождёт секунду и затем вернёт терминал в исходное состояние — фраза исчезнет:

import time
import curses


def draw(canvas):
    row, column = (5, 20)
    canvas.addstr(row, column, 'Hello, World!')
    canvas.refresh()
    time.sleep(1)
  
if __name__ == '__main__':
    curses.update_lines_cols()
    curses.wrapper(draw)

Функция curses.update_lines_cols() вычисляет размер экрана и кладет значения в curses.LINES and curses.COLS. Не спрашивайте почему, библиотека древняя и здесь все странно. Значения curses.LINES and curses.COLS пригодятся позже для изменения размеров canvas.

Функция wrapper готовит терминал к использованию:

  • Теперь ввод пользователя не отображается на экране.
  • Для ввода не нужно нажимать на Enter, ввод считывается побуквенно.
  • Специальные клавиши (PageUp, PageDown, Home, вверх, вниз и т. д.) теперь доступны как константы Curses.

После подготовки терминала функция def wrapper запустит функцию def draw и передаст ей один аргумент. В терминах curses его называют Window, но по поведению он больше похож на холст — canvas.

Когда выполнение def draw завершится, функция def wrapper вернёт терминал в исходное состояние и сотрет все что успела вывести функция def draw. Чтобы надпись ‘Hello, World!’ задержалась на экране, в def draw поставлена задержка в одну секунду — time.sleep(1).

Работа с холстом

В примере выше мы вывели на холст фразу «Hello, World!»:

row, column = (5, 20)
canvas.addstr(row, column, 'Hello, World!')
canvas.refresh()

Это делается за счёт метода холста «Добавь строку»: canvas.addstr(). Он принимает на вход строку и столбец, на которых нужно выводить текст, и сам текст. Но текст сразу не отобразится. Чтобы обновить экран, необходим вызов метода canvas.refresh().

В конце вывода будет мигающий символ курсора. Если вы хотите его отключить, добавьте вызов curs_set(False):

curses.curs_set(False)

Для вывода рамки есть готовый метод border. Нарисовать рамку по границе холста можно так:

canvas.border()

У методы border() много необязательных аргументов, они описаны в документации.

Атрибуты текста

При выводе текста можно изменить его стиль: включить bold или italic шрифт, притушить текст или сделать его мерцающим.

Атрибуты передаются четвертым аргументом в функцию canvas.addstr:

import curses

def draw(canvas):
    canvas.addstr(row, column, 'PRESS START', curses.A_BOLD)

Атрибуты можно комбинировать с помощью оператора “бинарного или” |:

import curses

def draw(canvas):
    canvas.addstr(row, column, 'PRESS START', curses.A_REVERSE | curses.A_BOLD)

Список атрибутов смотрите в документации.

Перехват ввода пользователя

Чтобы получить ввод от пользователя в Curses есть три метода:

  • canvas.getch() — обновляет холст и ждёт, когда пользователь нажмёт на кнопку. Возвращает ASCII-код нажатой клавиши.
  • canvas.getkey() — тоже ждёт ввода пользователя. На этот раз вернёт сам нажатый символ. Нажатия на специальные клавиши перехватятся с помощью, например, curses.KEY_HOME или curses.KEY_LEFT.
while True:
    char = canvas.getch()
    print(f"Вы ввели {char}")
    key = canvas.getkey()
    print(f"Вы ввели {key}")

Если вы введёте g, то canvas.getch() вернёт код буквы — 103. canvas.getkey() вернёт сам символ — g. Если вы нажмёте клавишу “вверх”, canvas.getch() вернёт код клавиши — 259. canvas.getkey() вернёт KEY_UP.

Если ввода пользователя ждать не хочется, можно вызвать функцию canvas.nodelay(True).


Попробуйте бесплатные уроки по Python

Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.

Переходите на страницу учебных модулей «Девмана» и выбирайте тему.