![](/img/trans.png)
[英]Java support for non-BMP Unicode characters (i.e. codepoints > 0xFFFF) in their Regular Expression Library?
[英]How to print non-BMP Unicode characters in Tkinter (e.g. 𝄫)
注意:从Python 3.8 开始,非 BMP 字符可以在 IDLE 中显示(因此,Tkinter 现在也可能显示它们,因为它们都使用 TCL),这是在我发布此问题后一段时间发布的。 我计划在试用 Python 3.9 之后(在我安装了 Xubuntu 的更新版本之后)进行编辑。 我也读过在 IDLE 中编辑这些字符可能不像其他字符那么简单; 请参阅此处的最后一条评论。
所以,今天我正在制作输入某些 Unicode 字符的快捷方式。 一切都很顺利。 然后,当我决定做这些字符时(在我的 Tkinter 程序中;他们甚至不会尝试进入 IDLE)、𝄫 和 𝄪,我遇到了一个奇怪的意外错误,我的程序开始删除我在文本框。 那是不能接受的。
这是错误: _tkinter.TclError: character U+1d12b is above the range (U+0000-U+FFFF) allowed by Tcl
我意识到我使用的大多数 Unicode 字符在代码中只有四个字符。 出于某种原因,它不喜欢五个。
那么,有没有办法在 ScrolledText 小部件中打印这些字符(更不用说不搞乱其他所有内容了)?
UTF-8 是我的编码。 我使用的是 Python 3.4(所以 UTF-8 是默认的)。
我可以用打印语句很好地打印这些字符。
输入字符而不只是使用 ScrolledText.insert(例如Ctrl-shift-u
,或通过在代码中执行此操作: b'\\xf0\\x9d\\x84\\xab'
)确实输入了它,没有那个错误,但它仍然开始疯狂地删除东西,或添加额外的空格(包括它自己,尽管它有时会随机重新出现)。
目前没有办法显示这些字符,因为它们应该在 Python 3.4 中的 Tkinter 中查看(尽管有人提到使用代理对可能如何工作 [在 Python 2.x] 中)。 但是,您可以实现将字符转换为可显示代码并返回的方法,并在必要时调用它们。 当您打印到文本小部件、复制/粘贴、文件对话框*、标签栏、状态栏和其他东西时,您必须调用它们。
*默认的 Tkinter 文件对话框不允许对对话框进行很多内部工程。 我制作了自己的文件对话框,部分是为了帮助解决这个问题。 如果您有兴趣,请告诉我。 希望我将来会在这里发布他们的代码。
这些方法将超出范围的字符转换为代码,反之亦然。 代码采用序数格式,如下所示: {119083ū}
。 括号和ū
只是为了将其区分为代码。 {119083ū}
代表𝄫
。 正如您所看到的,我还没有为转义代码而烦恼,尽管我确实有目的地尝试使代码不太可能发生。 转换时使用的ᗍ119083ūᗍ
也是如此。 无论如何,我的意思是最终添加转义序列。 这些方法取自我的班级(因此是self
)。 (是的,我知道您不必在 Python 中使用分号。我只是喜欢它们并认为它们在某些情况下使代码更具可读性。)
import re;
def convert65536(self, s):
#Converts a string with out-of-range characters in it into a string with codes in it.
l=list(s);
i=0;
while i<len(l):
o=ord(l[i]);
if o>65535:
l[i]="{"+str(o)+"ū}";
i+=1;
return "".join(l);
def parse65536(self, match):
#This is a regular expression method used for substitutions in convert65536back()
text=int(match.group()[1:-2]);
if text>65535:
return chr(text);
else:
return "ᗍ"+str(text)+"ūᗍ";
def convert65536back(self, s):
#Converts a string with codes in it into a string with out-of-range characters in it
while re.search(r"{\d\d\d\d\d+ū}", s)!=None:
s=re.sub(r"{\d\d\d\d\d+ū}", self.parse65536, s);
s=re.sub(r"ᗍ(\d\d\d\d\d+)ūᗍ", r"{\1ū}", s);
return s;
我的回答基于@Shule 的回答,但提供了更多 pythnoic 和易于阅读的代码。 它还提供了一个真实案例。
这是将项目填充到tkinter.Listbox
的方法。 没有反向转换。 此解决方案只负责显示带有 Tcl 不允许的字符的字符串。
class MyListbox (Listbox):
# ...
def populate(self):
"""
"""
def _convert65536(to_convert):
"""Converts a string with out-of-range characters in it into a
string with codes in it.
Based on <https://stackoverflow.com/a/28076205/4865723>.
This is a workaround because Tkinter (Tcl) doesn't allow unicode
characters outside of a specific range. This could be emoticons
for example.
"""
for character in to_convert[:]:
if ord(character) > 65535:
convert_with = '{' + str(ord(character)) + 'ū}'
to_convert = to_convert.replace(character, convert_with)
return to_convert
# delete all listbox items
self.delete(0, END)
# add items to listbox
for item in mydata_list:
try:
self.insert(END, item)
except TclError as err:
_log.warning('{} It will be converted.'.format(err))
self.insert(END, _convert65536(item))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.