Pythonのcursesライブラリで拡張文字を使用するにはどうすればよいですか?

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

  •  16-09-2019
  •  | 
  •  

質問

私は Python での Curses プログラミングに関するチュートリアルを読んでいますが、その多くは線画記号などの拡張文字を使用する機能について言及しています。これらは 255 を超える文字であり、curses ライブラリは現在の端末フォントで文字を表示する方法を知っています。

いくつかのチュートリアルでは、次のように使用すると述べています。

c = ACS_ULCORNER

...そして、次のように使用するという人もいます。

c = curses.ACS_ULCORNER

(これは、L を上下に反転したような、ボックスの左上隅であるはずです)

いずれにせよ、どの方法を使用しても、名前が定義されていないため、プログラムは失敗します。「import Curses」と「from Curses import *」を試しましたが、どちらも機能しません。

Curses の window() 関数はこれらの文字を使用するので、ソースを探してボックスを調べてみて、どのように機能するかを確認してみました。 それ やりますが、どこにも見つかりません。

役に立ちましたか?

解決

curses/__init__.pyから:

  

いくつかの定数は、最も顕著なACS_*   ものは、唯一のCに追加されます   _cursesinitscr()モジュールの辞書が呼び出されます。 (一部のバージョン   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()

出力: あ

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top