Python中的N-curses:如何捕获和打印非ASCII字符?

3
我想用ncurses / python编写一个小程序,使其能够使用/输入法语和日语。我知道应该设置区域设置并使用Unicode标准。
但是如何处理来自screen.getch()的结果?我想在ncurses窗口中显示键入的字符,而不管使用的语言是什么。
我知道需要进行一些Unicode转换,但找不到该怎么做(我已经搜索了很多:对于业余爱好者来说,这个字符转换业务并不容易理解)。
附加问题:似乎对于非ASCII字符,我们必须使用addstr()而不是addch()。同样,我是否应该使用getstr()而不是getch()?
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import curses
from curses import wrapper
import locale

locale.setlocale(locale.LC_ALL, '')

def main(scr):
    # Following lines are some sort of "proof of concept"
    # Indeed it print latin or japanese characters allright
    scr.addstr(0, 0, u'\u3042'.encode('utf-8')) # print あ
    scr.addstr(1, 0, 'é'.encode('utf-8'))       # print é

    # But here I would like to type in a character and have it displayed onscreen
    while (True):
        car = scr.getch()
        if car == 27: # = Escape key
            break
        else:
        # What should I put between those parenthesis to
        # print the typed character on the third line of the screen 
            scr.addstr(3, 0, ???? )

wrapper(main)

看起来您正在使用Linux或其他类Unix系统(而非Windows)。您能否确认一下,并且确认您不需要与Windows兼容? - Serge Ballesta
实际上,我正在使用Linux(基于Debian的发行版称为Bunsen Labs),我不需要Windows兼容性。 - Tapewormer
2个回答

3

unctrl 是一个函数,用来处理 getch 返回的结果:

curses.unctrl(ch)

返回一个字符串,表示字符 ch 的 可打印形式。控制字符以插入符号 (^) 后面接字符的方式显示,例如 ^C 表示 Ctrl+C。打印字符则保持不变。

如果你想直接读取 UTF-8 编码,可以使用 get_wch(这在 Python 2 中不可用):

window.get_wch([y, x])

获取一个宽字符。对于大多数键,返回一个字符,对于功能键、小键盘键和其他特殊键,则返回一个整数。在无延迟模式下,如果没有输入,则引发异常。

自版本3.3起新增。

即使如此,你仍然必须确保区域设置已初始化。Python文档假定您可以访问ncurses文档:


抱歉要说,被视为可打印字符的“é”不能保留原样。在打印时,它会变成M-)。这是否需要额外的转换步骤? - Tapewormer
当然 - 你必须告诉Python当前的语言环境是什么,否则在POSIX(默认)语言环境下该字符无法打印。 - Thomas Dickey

0

在Python中,getch/getkey存在问题。根据文档,它们应该在设置编码时返回一个字符,但实际上每次调用函数时它们会逐个返回UTF-8序列中的八位字节。您需要通过循环收集这些八位字节来解决此缺陷,直到您拥有完整的序列。当序列可以成功解码时,它就是完整的,否则就是不完整的。

与下面的程序进行比较,下面的程序可以正常运行(使用perl -C so-56373360.pl运行):

use Term::ReadKey qw(ReadKey ReadMode);
ReadMode 'raw';
while () {
    my $c = ReadKey 0;
    last if $c eq "\e"; # Escape
    print $c;
}
ReadMode 'restore';

感谢您的评论,我开始明白该寻找什么了! - Tapewormer
实际上,我只需要一个非常小的脚本就可以验证输入“qwer”时调用getch() 4次,而输入“bépo”时调用它5次(并发出两个类似ASCII的代码来表示“é”)。一开始试图弄清楚如何循环遍历以获取八位字节来构建有效的UTF-8代码,但同时我意识到,在我的特定情况下,使用addch()打印而不是addstr()解决了我的问题。 - Tapewormer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接