如何在Tkinter应用程序中启用对表情符号的支持?

时间:2018-09-07 20:00:00

标签: python tkinter emoji

我已经实施了Saurabh Chaturvedi的Python chat application,开始学习网络的工作原理。该应用程序很简单,并且使用了Tkinter模块。

我想通过允许用户在发送消息时在消息框中键入表情符号并在消息列表中将其呈现为表情符号来扩展应用程序的功能。例如,如果用户在消息框中键入“ :)”,则应显示为。

到目前为止,我已经研究了如何在Tkinter应用程序中启用对表情符号的支持。我遇到了Displaying emojis/symbols in Python using tkinter lib,但我认为它不能直接解决我的问题。我不确定目前是否要以正确的方式解决此问题。

如果有帮助,我正在运行Windows 10并使用Python3。并且您应该能够通过运行Saurabh’s article中所述的两个脚本(服务器和客户端)来实现聊天应用。 (另外,一个潜在的相关问题是表情符号在我的Python 3解释器中无法正确显示。例如,

>>> import emoji
>>> print(emoji.emojize(":thumbs_up:"))

在框中显示两个问号,而不是。)

关于如何使表情符号显示在消息列表中的任何建议?


编辑:

根据下面@abarnert的评论,值得一提的是,此问题不是不是的原因,这是我尝试使用表情符号库将用户的“ :)”转换为表情符号引起的。而是出现了最初的问题,因为首先我不确定如何进行基于Tkinter的应用程序中的“ :)”渲染。

1 个答案:

答案 0 :(得分:2)

您在这里遇到多个问题,但我不确定您遇到的是哪个问题,所以我将尽力介绍所有问题。


首先,如何“字符串化”字符串?

您需要准确定义这意味着什么-您将什么输入映射到什么输出,如果:8是输入,则意味着80:80应该将:8拨入中间是表情符号(如果不是,则说明为什么不这么做),等等。

那么实现起来并不难-无论是遍历s.split()还是更复杂的re.finditer,您的规则是否需要考虑当前模式之外的上下文等,取决于您选择了什么规则。

无论如何,PyPI上有许多库可以对此进行各种更改,并且您已经发现至少一个emoji。所以我假设这个问题已解决。


接下来,您如何将其连接到代码中?

大概有一个回调,只要用户提交聊天消息,就会触发该回调。我不知道您是如何设置的,但这并不重要,所以让我们组成一个简单的示例:

def callback(widget):
    msg = widget.get()
    conn.sendall(msg)
    msglog.append(f'>>> {msg}')

此函数从消息输入窗口小部件中获取字符串内容,然后两者都将该字符串发送到服务器,并将其显示在消息日志窗口小部件中。因此,您所需要做的就是:

def callback(widget):
    msg = widget.get()
    msg = emojify(msg)
    conn.sendall(msg)
    msglog.append(f'>>> {msg}')

第三,您如何处理tkinter无法正确处理表情符号(以及其他非BMP字符)的事实?

这部分是the question you linked的副本。 Tkinter有一个已知的错误,直到3.7为止仍然存在,并且最著名的解决方法是较丑陋的。

但是,尽管可能很丑陋,但并不是那么困难。该问题的答案链接到another question,其中Martijn Pieters提供了一个不错的with_surrogates函数,您可以仅调用已情绪化的字符串。

如果您想要一些简单但棘手的东西(这将使服务器基本上对没有问题的teminter客户端无效),则可以在通过网络发送消息之前做到这一点:

def callback(widget):
    msg = widget.get()
    msg = emojify(msg)
    tkmsg = with_surrogates(msg)
    conn.sendall(tkmsg)
    msglog.append(f'>>> {tkmsg}')

但是更干净的解决方案是将它们作为适当的UTF-8通过电线发送,并且仅在显示时代其使用:

def callback(widget):
    msg = widget.get()
    msg = emojify(msg)
    conn.sendall(msg)
    tkmsg = with_surrogates(msg)
    msglog.append(f'>>> {tkmsg}')

…以及在接收来自其他用户的消息的代码中:

def on_msg(msg):
    tkmsg = with_surrogates(msg)
    msglog.append(tkmsg)