![](/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.