Pythonのcursesライブラリで拡張文字を使用するにはどうすればよいですか?
質問
私は Python での Curses プログラミングに関するチュートリアルを読んでいますが、その多くは線画記号などの拡張文字を使用する機能について言及しています。これらは 255 を超える文字であり、curses ライブラリは現在の端末フォントで文字を表示する方法を知っています。
いくつかのチュートリアルでは、次のように使用すると述べています。
c = ACS_ULCORNER
...そして、次のように使用するという人もいます。
c = curses.ACS_ULCORNER
(これは、L を上下に反転したような、ボックスの左上隅であるはずです)
いずれにせよ、どの方法を使用しても、名前が定義されていないため、プログラムは失敗します。「import Curses」と「from Curses import *」を試しましたが、どちらも機能しません。
Curses の window() 関数はこれらの文字を使用するので、ソースを探してボックスを調べてみて、どのように機能するかを確認してみました。 それ やりますが、どこにも見つかりません。
解決
curses/__init__.py
から:
いくつかの定数は、最も顕著な
ACS_*
ものは、唯一のCに追加されます_curses
後initscr()
モジュールの辞書が呼び出されます。 (一部のバージョン SGIの呪いの値を定義していません。initscr()
までこれらの定数について 呼ばれている。)このラッパー 機能は、基礎となるCを呼び出しますinitscr()
、その後、コピー からの定数 呪いパッケージの辞書に_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
, 、Unicode 文字「π」が表示されます。ただし、検査してみると、 ACS_PI
, 、値が 4194427 (0x40007b) の整数であることがわかります。したがって、以下は同じ文字 (または評価者、グリフ?) 'π' もレンダリングします。
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 関数 (ただし、最終的には するだろう VT-100 をエミュレートする場合でも、Unicode コード ポイントを返します)。そのため、次の仕様になっています。
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
一定です(そして、それらの数もそれほど多くありません)。
これが誰かの役に立てば幸いです、
乾杯!
あなたは次のように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()
出力: あ