【问题标题】:How can I enable support for emoji in Tkinter applications?如何在 Tkinter 应用程序中启用对表情符号的支持?
【发布时间】:2019-02-13 04:26:42
【问题描述】:

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

我想扩展应用程序的功能,使用户能够在消息框中键入表情符号,并在他们发送消息时将它们呈现为消息列表中的表情符号。例如,如果用户在消息框中键入“:)”,它应该呈现为 ????。

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

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

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

在方框中产生两个问号,而不是????。)

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


编辑:

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

【问题讨论】:

  • 您链接的问题解释了为什么这不起作用,以及解决问题的方法。如果您正在寻找一种不那么痛苦的方法来解决这个问题,那么没有一种方法。如果您正在寻找与该问题无关的任何其他信息,您在寻找什么信息?
  • 至于您的相关问题:显示表情符号可能不是您的 Python 3 解释器,而是终端(例如,Windows cmd.exe)或终端式的东西(例如,输出窗口)在 IDLE 或 PyCharm 中)。如果您想问这个问题,请创建一个单独的问题并包含有关该问题的详细信息(尽管它可能是重复的,因此请先搜索)。
  • 没什么大不了的:tkinter 无法处理表情符号(或任何其他非 BMP 字符),因为他的回答中描述了 Donal Fellows 的错误。这正是您遇到的问题:emojize 可能工作正常,为您提供完美的表情符号字符,但 tkinter 无法处理它们。自 Python 3.7 起,该错误尚未修复,唯一的解决方法是他描述的那个。
  • 我没有关注所有链接,所以我不会发布答案,但你能插入图片而不是文本吗?这需要做更多的工作,但是无论如何,很多 tk 小部件都支持图像......这个想法基本上是在显示输出之前对输出进行标记,然后显示一个 tk 标签流,这些标签可以是文本或图片......或者类似的东西那
  • 基本上,您需要做的就是,无论您在哪里调用emoji.emojize(s),而不是调用with_surrogates(emoji.emojize(s)),使用链接问题中的Martijn Pieters 的with_surrogates 函数。

标签: python tkinter emoji


【解决方案1】:

您在这里遇到了多个问题,我不确定您遇到了哪一个问题,所以我会尝试涵盖所有问题。


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

您需要准确定义这意味着什么——您将哪组输入映射到什么输出,如果: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 函数,您只需调用您的表情符号字符串即可。

如果你想要一些简单但很老套的东西——这将使服务器基本上对任何东西都无用一个有缺陷的 tkinter 客户端——你可以在通过网络发送消息之前这样做:

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)

【讨论】:

  • 您在将我的原始问题分解为我正在寻找的子问题方面做得很好。
猜你喜欢
  • 1970-01-01
  • 2014-06-04
  • 2010-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多