Как мне использовать расширенные символы в библиотеке curses Python?

StackOverflow https://stackoverflow.com/questions/1279341

  •  16-09-2019
  •  | 
  •  

Вопрос

Я читал учебные пособия по программированию Curses на Python, и многие из них ссылаются на возможность использования расширенных символов, таких как символы рисования линий.Это символы > 255, и библиотека curses знает, как отобразить их в текущем шрифте терминала.

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

c = ACS_ULCORNER

... и некоторые говорят , что вы используете это вот так:

c = curses.ACS_ULCORNER

(Предполагается, что это верхний левый угол прямоугольника, как буква L, перевернутая вертикально)

В любом случае, независимо от того, какой метод я использую, имя не определено, и программа, таким образом, завершается с ошибкой.Я попробовал "импортировать проклятия" и "импортировать из проклятий *", но ни то, ни другое не работает.

Функция window () Curses использует эти символы, поэтому я даже попытался покопаться в своем окне в поисках источника, чтобы увидеть, как IT делает это, но я нигде не могу его найти.

Это было полезно?

Решение

От curses/__init__.py:

Некоторые константы, в первую очередь ACS_* единицы, добавляются только к C _curses словарь модуля после initscr() называется.(Некоторые версии проклятий SGI не определяют значения для этих констант до initscr() был вызван.) Эта оболочка функция вызывает базовый C initscr(), а затем копирует константы из _curses модуль к словарю пакета curses.Не делай этого 'from curses import *' если вам понадобится ACS_* константы.

Другими словами:

>>> import curses
>>> curses.ACS_ULCORNER
exception
>>> curses.initscr()
>>> curses.ACS_ULCORNER
>>> 4194412

Другие советы

Я считаю, что приведенное ниже имеет соответствующую связь и должно быть опубликовано в разделе этот вопрос.Здесь я буду использовать utfinfo.pl (смотрите также на Суперпользователь).

Прежде всего, для стандартного набора символов ASCII кодовая точка Unicode и байтовая кодировка одинаковы:

$ echo 'a' | perl utfinfo.pl 
Char: 'a' u: 97 [0x0061] b: 97 [0x61] n: LATIN SMALL LETTER A [Basic Latin]

Таким образом, мы можем сделать в Python curses:

window.addch('a')
window.border('a') 

...и это работает так, как задумано

Однако, если символ находится выше базового ASCII, то существуют различия, которые addch Документы не обязательно делать это явно.Во-первых, я могу сделать:

window.addch(curses.ACS_PI)
window.border(curses.ACS_PI)

...в этом случае, по моему gnome-terminal, отображается символ Юникода 'π'.Однако, если вы проверите ACS_PI, вы увидите, что это целое число со значением 4194427 (0x40007b);таким образом, следующее также отобразит тот же символ (или rater, глиф?) 'π':

window.addch(0x40007b)
window.border(0x40007b)

Чтобы посмотреть, что происходит, я просмотрел ncurses источник, и обнаружил следующее:

#define ACS_PI      NCURSES_ACS('{') /* Pi */  
#define NCURSES_ACS(c)  (acs_map[NCURSES_CAST(unsigned char,c)])
#define NCURSES_CAST(type,value) static_cast<type>(value)
#lib_acs.c: NCURSES_EXPORT_VAR(chtype *) _nc_acs_map(void): MyBuffer = typeCalloc(chtype, ACS_LEN);
#define typeCalloc(type,elts) (type *)calloc((elts),sizeof(type))
#./widechar/lib_wacs.c: { '{',  { '*',  0x03c0 }},  /* greek pi */

Обратите внимание здесь:

$ echo '{π' | perl utfinfo.pl 
Got 2 uchars
Char: '{' u: 123 [0x007B] b: 123 [0x7B] n: LEFT CURLY BRACKET [Basic Latin]
Char: 'π' u: 960 [0x03C0] b: 207,128 [0xCF,0x80] n: GREEK SMALL LETTER PI [Greek and Coptic]

...ни одно из которых не относится к значению 4194427 (0x40007b) для ACS_PI.

Таким образом, когда addch и/или border смотрите символ выше ASCII (в основном это unsigned int, в отличие от unsigned char), они (по крайней мере, в данном случае) используют это число не как кодовая точка Unicode или как представление байтов в кодировке UTF-8 - но вместо этого они используют ее в качестве поискового индекса для acs_map-функция ping (которая в конечном счете, однако, бы возвращает кодовую точку Unicode, даже если она эмулирует VT-100).Вот почему следующая спецификация:

window.addch('π') 
window.border('π') 

завершится неудачей в Python 2.7 с argument 1 or 3 must be a ch or an int;а в Python 3.2 будет отображаться просто пробел вместо символа.Когда мы указываем 'π'.на самом деле мы указали кодировку UTF-8 [0xCF, 0x80], но даже если мы укажем кодовую точку Unicode:

window.addch(0x03C0) 
window.border0x03C0) 

...он просто ничего не отображает (пробел) как в Python 2.7, так и в 3.2.

При этом, как говорится, функция addstr делает принимает строки в кодировке UTF-8 и работает нормально:

window.addstr('π')

...но для границ - с border() по-видимому, обрабатывает символы таким же образом addch() делает - нам, по-видимому, не повезло, ни для чего явно не указанного как ACS постоянные (и их тоже не так уж много).

Надеюсь, это кому-то поможет,
Ваше здоровье!

вы должны установить для своего локального значения значение all, затем закодировать свои выходные данные в формате utf-8 следующим образом:

import curses
import locale

locale.setlocale(locale.LC_ALL, '')    # set your locale

scr = curses.initscr()
scr.clear()
scr.addstr(0, 0, u'\u3042'.encode('utf-8'))
scr.refresh()
# here implement simple code to wait for user input to quit
scr.endwin()

выходной сигнал:あ

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top