Выделение и выделение текста с помощью Python curses - PullRequest
8 голосов
/ 24 июля 2011

Это мой первый пост с переполнением стека. Я годами скрываю информацию на этом сайте, и она всегда полезна, поэтому я решила опубликовать свой первый вопрос.

Я искал похожие примеры, но, похоже, ничего не нашел.

В конечном счете, я пытаюсь написать простой текстовый интерфейс для поиска ложных срабатываний и ложных отрицаний в программе извлечения текста. Модуль ложных срабатываний - это простой выбор да / нет, а отображение цветного текста и использование getch () достаточно просты. Однако ложная отрицательная часть становится трудной.

Вот что я хочу сделать:

  1. Вывести строку на экран (пока не забудьте прокрутить .... тьфу) Это будет только строка без перевода строки.
  2. Пользователь видит текст и нажимает «h», чтобы войти в режим выделения.
  3. Затем пользователь может управлять курсором, перемещая его над частью текста (все еще отображается), и выбирать 'v', чтобы начать выделение (я пытаюсь сделать это как можно ближе к vi)
  4. Затем пользователь использует клавиши управления (стрелки, hjkl) для перемещения курсора от начальной точки к конечной точке, выделяя текст на пути. Эта выделенная часть должна быть словом, которое является ложным отрицанием
  5. Пользователь нажимает какую-то клавишу (вероятно, 'y'), и выделенный текст окрашивается или остается выделенным, а выделенный текст сохраняется в некоторой переменной, с которой я буду работать позже.
  6. Пользователь выходит из режима выделения и продолжает.

Есть идеи, чтобы даже начать? Я пробую простые вещи, такие как удержание текста на экране и перемещение курсора, но безрезультатно.

Мне известен модуль curses.textpad.TextBox (), но он выполняет редактирование, например вставку и удаление, чего я не хочу делать. Возможно, есть способ отключить его.

У меня есть другие вопросы, но я пока оставлю это конкретным.

Спасибо !!

Нил

Редактировать: если быть более точным, я не ищу помощи в написании всей программы, просто помогаю навести курсор на отображаемый текст, выделить его, выбрать его и сохранить в переменной.

Ответы [ 2 ]

13 голосов
/ 27 июля 2011

Я хотел бы обновить этот вопрос на тот случай, если кто-то еще ищет в Интернете это и наткнется на этот вопрос.

Хорошо, поэтому ответ был довольно простым и требовал чтения всех функций, перечисленных в документации по python curses.

Что я сделал, так это сделал конечный автомат 3: State 1: обычный режим (отображает только текст), State 2: режим выделения, позволяет перемещать курсор по окну и State 3: режим выделения, который дает только ограниченный движение слева направо над текстами и выделяет текст по мере его движения.

Чтобы выполнить эту задачу, достаточно просто вызвать несколько основных функций curses.

Я сделал отдельные окна, но я просто возьму одно окно для объяснения.

Отображать текст в окне, придерживайтесь:

window.addstr()
window.refresh()

Для перемещения курсора:

#get current cursor position
curr_y, curr_x = window.getyx()

# depending on direction, update the cursor with
next_y, next_x = get_next_direction()

# place cursor in new position
window.move(next_y, next_x)

window.refresh()

Как только курсор окажется над начальной точкой для выделения, нажмите 'v', войдите в состояние выделения и ограничьте движение курсора, измените атрибут выделенного текста:

# get current cursor position
curr_y, curr_x = window.getyx()

# save position for later use
start_y = curr_y; start_x = curr_x

# loop until 'v' is pressed again
while highlight_state:
    # change the attribute of the current character, for 1 character only, to reverse
    window.chgat(curr_y,curr_x, 1, curses.A_REVERSE)
    curr_y, curr_x = get_next_direction()

# save end state, this is buggy obviously, but you get the point
end_y = curr_y; end_x = curr_X

Теперь извлеките эту информацию от начала до конца

# get integer representation of char at positiong

outstr = ''
#from start to end
char_as_int = windows.inch(y,x)
char = char_as_int & 0000FF
attr = char_as_int & FFFF00 #not useful here, but maybe later

outstr += char

Вот и все! Я также попробовал другой способ сохранить выделенный материал, который в основном преобразовывал координаты x, y в индекс отображаемой строки, но который позволял выпускать в представлении строки (переводы строки, табуляции и т. Д.), Плюс был просто сложнее сделать.

Если у кого-то есть комментарии относительно более эффективного / чистого метода, пожалуйста, ответьте!

0 голосов
/ 24 июля 2011

Я ничего не знаю о ncurses, но используя Tkinter или один из других наборов инструментов GUI, это можно сделать с помощью canvas.Сначала нужно установить область прокрутки, затем связать клавишу «h», чтобы она установила для переменной подсветки значение «True», привязать щелчок мыши к функции, которая извлекает местоположение для начала, привязать стрелки влево и вправо для перемещения влево или вправобукву, переместите курсор и поменяйте местами цвета следующей буквы, а также отследите, сколько букв вы находитесь в начальной точке, которая также сообщает вам конечное местоположение, и свяжите «y», чтобы скопировать текст.

Это не так сложно, как может показаться, поскольку каждая часть является довольно простой функцией.Все это, конечно, будет зависеть от размера шрифта, и я бы предложил отображать текст с фиксированным шрифтом, чтобы каждая буква занимала одинаковую ширину.Еще раз, я не знаю ncurses, но это было бы похоже на любой инструментарий.Если вы можете обойти это так, чтобы пользователь мог выделить одну целую строку одним щелчком мыши, это значительно облегчит кодирование.Отправьте сообщение с некоторым кодом, если вы действительно решили использовать Tkinter или wxPython и хотите получить дополнительную помощь.

...