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

Cal*_*oma 6 python tkinter emoji

我已经实现了 Saurabh Chaturvedi 的这个Python 聊天应用程序,开始学习网络是如何工作的。该应用程序很简单,并使用了 Tkinter 模块。

我想通过允许用户在消息框中键入表情符号并在他们发送消息时将它们呈现为消息列表中的表情符号来扩展应用程序的功能。例如,如果用户在消息框中键入 ':)',它应该呈现为 .

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

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

>>> import emoji
>>> print(emoji.emojize(":thumbs_up:"))
Run Code Online (Sandbox Code Playgroud)

导致框中出现两个问号,而不是 。)

关于如何在消息列表中呈现表情符号的任何建议?


编辑:

根据下面@abarnert 的评论,值得一提的是,这个问题并非源于我尝试使用表情符号库将用户的“:)”转换为表情符号。相反,最初的问题是因为我不确定如何在基于 Tkinter 的应用程序中执行“:)”的渲染,首先。

aba*_*ert 8

您在这里遇到了多个问题,我不确定您遇到了哪个问题,所以我会尽量涵盖所有内容。


首先,你如何“emojify”一个字符串?

您需要准确定义这意味着什么 - 您将哪些输入映射到哪些输出,如果:8是输入是否意味着80:80应该将:8中间的变成表情符号(如果不是,那么规则究竟是什么?为什么不)等。

那么它并不难实现——无论你是循环s.split()还是更复杂的re.finditer,你的规则是否需要考虑当前模式之外的上下文,等等取决于你选择的规则。

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


接下来,你在哪里将它挂钩到你的代码中?

据推测,只要用户提交聊天消息,就会触发一个回调。我不知道你是如何设置的,但这并不重要,所以让我们举一个简单的例子:

def callback(widget):
    msg = widget.get()
    conn.sendall(msg)
    msglog.append(f'>>> {msg}')
Run Code Online (Sandbox Code Playgroud)

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

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

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

这部分是您链接的问题的重复。Tkinter 有一个已知的错误,它在 3.7 中仍然存在,而最著名的解决方法有点难看。

但是,虽然它可能很难看,但并不。该问题的答案链接到另一个问题,其中 Martijn Pieters 提供了一个很好的with_surrogates函数,您只需调用您的表情符号字符串即可。

如果你想要的东西简单,但哈克,这将使服务器与任何东西基本没用,但是一车Tkinter的客户,你可以做到这一点发送过线的消息之前:

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

但更简洁的解决方案是将它们作为正确的 UTF-8 通过网络发送,并且仅将其代理用于显示,两者都在这里:

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

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

def on_msg(msg):
    tkmsg = with_surrogates(msg)
    msglog.append(tkmsg)
Run Code Online (Sandbox Code Playgroud)