【问题标题】:N-curses within Python : how to catch and print non ascii character?Python 中的 N 诅咒:如何捕捉和打印非 ascii 字符?
【发布时间】:2019-10-15 19:42:24
【问题描述】:

我想用 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兼容?
  • 确实我使用的是 linux(基于 debian 的发行版,称为 bunsen labs),我不需要 windows 兼容性。

标签: python unicode ncurses non-ascii-characters python-curses


【解决方案1】:

unctrl 是要使用的函数,用于来自getch 的结果:

curses.unctrl(ch)

返回一个字符串,它是字符 ch 的可打印表示。控制字符显示为插入字符后跟字符,例如 ^C。打印字符保持原样。

如果您想直接读取 UTF-8,请使用 get_wch(在 python2 包装器中不可用):

window.get_wch([y, x])

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

3.3 版本中的新功能。

即使使用 that,您仍然必须确保已初始化语言环境。 Python 文档假定您可以访问 ncurses 文档:

【讨论】:

  • 很抱歉,应该算作打印字符的“é”没有保持原样。打印后变为 M-) 。是否有额外的转换步骤?
  • 当然——你必须告诉 python 语言环境是什么——否则,该字符在 POSIX(默认)语言环境中是不可打印的。
【解决方案2】:

getch/getkey 在 Python 中被破坏。当编码设置为记录时,它们应该返回一个字符,但是每次调用函数时,它们都会从 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';

【讨论】:

  • 感谢您的评论,我开始明白要寻找什么了!
  • 确实用一个非常小的脚本,我可以验证输入“qwer”调用 getch() 4 次,而输入“bépo”调用它 5 次(并为“é”发出两个类似 ASCII 的代码) .试图弄清楚如何通过循环获取八位字节来构建有效的 utf-8 代码,同时我意识到在我的特殊情况下使用 addch() 打印而不是 addstr() 解决了我的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-27
  • 2014-04-23
相关资源
最近更新 更多