如何在tkinter中插入特殊字符

时间:2019-04-02 20:44:49

标签: python tkinter

我正在用tkinter创建一个GUI,在该GUI中,用户必须填写一些条目小部件,输入内容将存储在文件中。 我面临的问题是用户无法在这些输入小部件中插入特殊字符(如表情符号)。

我发现了一些显示它们的方法...:

...但是我没有发现有关我的问题的任何信息。
我考虑过通过在条目附近显示带有表情符号的表和相关代码以将其插入条目中而不是直接插入表情符号的方式来解决问题,因此如下所示:...
1:2:3:4:
...并让用户插入1、2、3或4而不是表情符号,但我认为这不是解决问题的好方法。

从我的研究中,我了解到问题出在tkinter模块中,我想知道是否有解决方法。

'\uD83D\uDE05'

这是问题的一个示例,我有一个带有Entry小部件的窗口,用户可以在其中插入表情符号,但是如果用户插入表情符号,则代码会引发以下错误:

# -*- coding: utf-8 -*-
from tkinter import *

def sumbit():
    print(var.get())

root = Tk()
root.tk.call('encoding', 'system', 'utf-8')

var = StringVar()
entry = Entry(root, textvariable=var)
entry.pack()
button = Button(root, text="sumbit", command=sumbit)
button.pack()

root.mainloop()

我正在使用Windows和Pyton 3.7

1 个答案:

答案 0 :(得分:0)

我现在已经解决了这个问题:

# -*- coding: utf-8 -*-
from tkinter import *
import tkinter.font as tkFont

# Dict with all the emojis
# it is made in this format -->    EMOJI_NAME: EMOJI_SURROGATE_PAIR
emoji_dict = {
    "GRINNING_FACE": '\ud83d\ude00',
    "GRINNING_FACE_WITH_BIG_EYES": '\ud83d\ude03',
    "GRINNING_FACE_WITH_SMILING_EYES": '\ud83d\ude04',
    "BEAMING_FACE_WITH_SMILING_EYES": '\ud83d\ude01',
    "GRINNING_SQUINTING_FACE": '\ud83d\ude06',
    "GRINNING_FACE_WITH_SWEAT": '\ud83d\ude05',
    "LAUGHING_ON_THE_FLOOR": '\ud83e\udd23',
    "TEARS_OF_JOY": '\ud83d\ude02',
    "SMILING_FACE_SLIGHTLY": '\ud83d\ude42',
    "UPSIDE-DOWN_FACE": '\ud83d\ude43',
    "WINKING_FACE": '\ud83d\ude09',
}

emoji_num_name = dict()
emoji_name_num = dict()
counter = 0
for key in emoji_dict:
    emoji_num_name[counter] = key
    emoji_name_num[key] = counter
    counter += 1


def search(text):
    for widget in emoji_frame.winfo_children():
        if isinstance(widget, Button):
            widget.destroy()

    emoji_name_list = list(emoji_dict.keys())
    emoji_name_list.sort()
    if text == "" or text == " ":
        creates_emojis()
    else:
        x = 10
        y = 0
        for emoji_name in emoji_name_list:
            if emoji_name.startswith(text):
                emoji_code = emoji_dict[emoji_name]
                code_ = emoji_name_num[emoji_name]
                emoji_button = Button(emoji_frame, text=emoji_code, borderwidth=0, font=customFont)
                emoji_button.place(x=x, y=y)
                emoji_button.bind("<Button-1>", lambda event, code=code_, var=sumbit_var: insert_emoji(var, ":-" + str(code) + "-:"))

                if x <= 150:
                    x += 30
                else:
                    x = 10
                    y += 30
        emoji_frame.configure(widt=200, height=y+60)


def insert_emoji(var, code):
    var.set(var.get() + code)


def creates_emojis():
    x = 10
    y = 0
    for emoji_name in emoji_dict:
        emoji_code = emoji_dict[emoji_name]
        code_ = emoji_name_num[emoji_name]
        emoji_button = Button(emoji_frame, text=emoji_code, borderwidth=0, font=customFont)
        emoji_button.place(x=x, y=y)
        emoji_button.bind("<Button-1>", lambda event, code=code_, var=sumbit_var: insert_emoji(var, ":-" + str(code) + "-:"))

        if x <= 150:
            x += 30
        else:
            x = 10
            y += 30
    emoji_frame.configure(widt=200, height=y+60)


def sumbit(text):
    text = text.split(":-")
    for index in range(len(text)):
        word = text[index]
        word = word.split("-:")
        for index_ in range(len(word)):
            little_word = word[index_]
            if little_word.isdigit():
                emoji_name = emoji_num_name[int(little_word)]
                emoji = emoji_dict[emoji_name]
                word[index_] = emoji
        text[index] = "".join(word)
    text = "".join(text)
    text = text.encode('utf-16', 'surrogatepass').decode('utf-16')
    print(text)


root = Tk()
root.tk.call('encoding', 'system', 'utf-8')
root.configure(width=500, height=500)
font = "Courier"
customFont = tkFont.Font(family=font, size=14)

emoji_frame = LabelFrame(text="emojis")
emoji_frame.place(x=10, y=60)

search_var = StringVar()
search_entry = Entry(root, textvariable=search_var)
search_entry.place(x=10, y=10)
search_button = Button(root, text="search", command=lambda: search(search_var.get().upper()))
search_button.place(x=10, y=30)
displat_all_button = Button(root, text="display all", command=lambda: creates_emojis())
displat_all_button.place(x=60, y=30)

sumbit_var = StringVar()
sumbit_entry = Entry(root, textvariable=sumbit_var)
sumbit_entry.place(x=200, y=10)
sumbit_button = Button(root, text="sumbit", command=lambda: sumbit(sumbit_var.get()))
sumbit_button.place(x=200, y=30)
creates_emojis()

root.mainloop()

这是我所做的一个可运行的示例,我创建了一种表,您可以在其中插入任意数量的表情符号(通过编辑emoji_dict并插入所需的表情符号)并返回utf-8中的输出。

要查找我使用过代码的emoji surrogate pair

import re

_nonbmp = re.compile(r'[\U00010000-\U0010FFFF]')

def _surrogatepair(match):
    char = match.group()
    assert ord(char) > 0xffff
    encoded = char.encode('utf-16-le')
    return (
        chr(int.from_bytes(encoded[:2], 'little')) +
        chr(int.from_bytes(encoded[2:], 'little')))

def with_surrogates(text):
    return _nonbmp.sub(_surrogatepair, text)


emoji_dict = {
    "Grinning_Face": u'\ud83d\ude00',
    "Grinning_Face_With_Big_Eyes": u'\ud83d\ude03',
    "Grinning_Face_With_Smiling_Eyes": u'\ud83d\ude04',
    "Beaming_Face_With_Smiling_Eyes": u'\ud83d\ude01',
    "Grinning_Squinting_Face": u'\ud83d\ude06',
    "Grinning_Face_With_Sweat": u'\ud83d\ude05',
    "Laughing_on_the_Floor": u'\ud83e\udd23',
    "Tears_of_Joy": u'\ud83d\ude02',
    "Smiling_Face_Slightly": u'\ud83d\ude42',
    "Upside-Down_Face": u'\ud83d\ude43',
    "Winking_Face": u'\ud83d\ude09',
}

emoji_list =[ "", "", "", "", "", "", "", "", "",  "", "", ]


for emoji in emoji_list:
    print(repr(_nonbmp.sub(_surrogatepair, emoji)))

您可以在此问题上找到它 Python: Find equivalent surrogate pair from non-BMP unicode char