繁体   English   中英

如何在Python的curses库中使用扩展字符?

[英]How do I use extended characters in Python's curses library?

我一直在阅读有关Python中Curses编程的教程,许多人都提到使用扩展字符的能力,例如线条图符号。 它们的字符数> 255,curses库知道如何以当前终端字体显示它们。

一些教程说你像这样使用它:

c = ACS_ULCORNER

...有些人说你像这样使用它:

c = curses.ACS_ULCORNER

(那应该是一个盒子的左上角,就像L垂直翻转)

无论如何,无论我使用哪种方法,都没有定义名称,因此程序失败了。 我试过“import curses”和“from curses import *”,但都没有用。

Curses的window()函数使用了这些字符,所以我甚至尝试在我的盒子上寻找源代码来查看是如何做到的,但我无法在任何地方找到它。

来自curses/__init__.py

一些常量,特别是ACS_* ,只在initscr()后添加到C _curses模块的字典中。 (有些版本的SGI的curses在调用initscr()之前不会定义这些常量的值。)此包装函数调用底层的C initscr() ,然后将常量从_curses模块复制到curses包的字典中。 如果您需要ACS_*常量,请不要执行' from curses import * '。

换一种说法:

>>> 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 ,呈现Unicode字符“π”。 但是,如果你检查ACS_PI ,你会看到它是一个整数,值为4194427(0x40007b); 所以下面也会呈现相同的字符(或rater,glyph?)'π':

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]

...两者都与ACS_PI的4194427(0x40007b)的值ACS_PI

因此,当addch和/或border见上文ASCII字符(基本上是一个unsigned int ,而不是unsigned char ),它们(至少在本例中)使用该号码不是作为Unicode代码点,或为UTF-8编码的字节表示 - 但相反,他们将它用作acs_map函数的查找索引(但最终返回Unicode代码点,即使它模拟VT-100)。 这就是为什么以下规范:

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

argument 1 or 3 must be a ch or an int 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 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM