为什么tkinter(或turtle)似乎缺失或损坏?它不应该是标准库的一部分吗?

16

当尝试使用Tkinter标准库包或其相关功能(使用turtle和内置的IDLE IDE进行海龟绘图,或使用以此为依赖项的第三方库(例如使用Matplotlib显示图形窗口)时,我看到了许多不同的问题。

似乎即使没有由于遮蔽标准库模块名称而引起的问题(这是初学者尝试跟随教程并使用海龟绘图时的常见问题-example 1; example 2; example 3; example 4),标准库Tkinter通常也无法正常工作。这是一个大问题,因为很多初学者尝试跟随使用海龟绘图的教程,并盲目地假设turtle标准库将存在。

错误可能会报告:

  • 如出现ModuleNotFoundError: No module named 'tkinter'的错误;或者包含相同信息的ImportError错误;或者大小写不同(我知道在2.x中名称从Tkinter更改为3.x中的tkinter,但那是另一个问题)。

  • 类似地,但是指的是内部的_tkinter模块,并显示一段带有注释的代码,该注释说“如果失败,则Python可能未配置为Tk”; 或者具有自定义错误消息,该消息说“请安装python-tk包”或类似消息。

  • 当尝试特定使用turtle时出现“找不到turtle模块”的错误,或者出现上述任何一种错误。

  • 当尝试使用Matplotlib显示绘图时常见的情况是,在尝试更改后端之后发生了这种情况,默认情况下设置以避免尝试使用Tkinter。

为什么会出现像这样的问题,当Tkinter被记录为标准库的一部分时?我该如何添加或修复缺失的标准库功能?对于特定的Python环境是否有任何特别考虑?

另请参见:{{link1:“UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.” when plotting figure with pyplot on Pycharm}}。使用Matplotlib显示图形可以使用其他GUI后端,但如果TkAgg后端不起作用,则可能是由于缺少或损坏的Tkinter安装。

在Python 3.x中,为了保持一致的命名约定,将Tkinter标准库模块的名称从Tkinter更正为tkinter(即全部小写)。请使用Difference between tkinter and Tkinter关闭由于尝试在3.x中使用旧名称(或在2.x中使用新名称)而引起的重复问题。本问题涉及Tkinter实际上不可用的情况。如果不清楚适用哪种情况,请提供两个重复链接或将问题关闭为“需要调试详细信息”。


5
这是一个人工规范重复的尝试。我已经标记了几个问题,要将它们转移到这里;我希望这个问题能成为大多数新问题更好的重复目标,但其中一些受欢迎的问题应该保持开放状态。 - Karl Knechtel
2
你为什么要将旧问题标记为此新问题的重复?如果这个问题是较新的,那么它难道不是旧问题的重复吗? - Carl G
2
关闭一个已经超过8年,得分接近400且被查看了900,000次的问题,将其作为“人为规范”的重复问题来关闭似乎有点过度。 - Adrian Mole
3
@CarlG,考虑决定哪个问题是重复问题时,年龄不是一个因素。应该使用每个问题及其答案的质量来确定哪个是“副本”,哪个是规范的。请参见https://meta.stackoverflow.com/a/252017/354577。 - Chris
抱歉,但这篇文章读起来更像是一篇博客文章或教程,而不是一个问题/答案(这是Stack Overflow的重点)。 - undefined
显示剩余7条评论
4个回答

24

警告:不要使用pip尝试解决问题

Pip软件包管理器无法帮助解决问题。Python标准库的任何部分 - 包括tkinterturtle等 - 都不能从PyPI安装。出于安全原因,PyPI现在阻止使用与标准库匹配的名称的软件包。

PyPI上有许多看起来合适的包,但实际上并不是。大多数只是尝试为标准库Tkinter添加一些功能的包装器。然而,一个特别棘手的包是turtle。它不应该存在,因为当前政策(自2017年以来)是阻止与标准库名称匹配的包;但它在很久以前就被上传了,并且自那时以来没有得到维护。它是Python 2.x特定代码,在Python 3上安装时会出现错误,已经非常过时(发布于2009年),最重要的是与海龟图形毫无关系。我目前正在努力将其从PyPI中删除。

为什么某些Python安装不包括Tkinter组件

有几个原因可能导致Tkinter缺失,这取决于平台(尽管通常,动机可能只是为了节省空间)。

  • 当在Windows上使用官方安装程序安装Python时,有一个选项可以选择包含或排除Tcl/Tk支持。

  • 预安装在Linux上的Python可能会根据发行版维护者的政策排除Tkinter或各种组件。例如,我的Linux副本附带的Python包括标准库,但不包括底层的Tkinter包:

    >>> import turtle
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib/python3.8/turtle.py", line 107, in <module>
        import tkinter as TK
    ModuleNotFoundError: No module named 'tkinter'
    

    其他版本也可能不包括模块。

  • 从源代码构建的Python可能会缺少Tkinter支持,因为配置选项是故意选择的,或者在开始编译之前缺少依赖项。

请注意,虚拟环境通常具有与其基于的Python安装相同的Tkinter支持。但是,将Tkinter支持添加到基础程序中可能不会更新虚拟环境。在这种情况下,需要从头重新创建虚拟环境。无法为单个虚拟环境添加或删除Tkinter支持。这是因为虚拟环境仅在网站包方面与其基础程序不同,并且没有Tkinter的网站包(因为它是标准库组件,无法使用Pip获得)。

如何根据环境添加Tkinter支持

另请参阅

Windows

对于使用python.org官方安装程序安装的Python,请使用操作系统功能选择“修复安装”(或者,如果可行的话,卸载并重新安装Python)。 这次,请确保勾选“安装tcl/tk和IDLE”可选功能。

某些旧版本 可能存在Python和Tcl/Tk的32位和64位版本之间的冲突问题。这不会在新设置上引起问题。

对于可嵌入的zip包,请参见Python可嵌入zip:安装Tkinter

Linux:随Linux发行版提供的Python

如果随Linux发行版提供的Python不包括Tkinter,则可以考虑放弃该版本并安装单独的Python版本 - 凭借一般原则。然而,通常情况下,可以使用系统软件包管理器(而非Pip)系统Python添加Tkinter支持

通常需要使用sudo(本文未包含在示例中)来进行对系统Python的更改。

在基于Ubuntu和Debian的系统(包括Pop!_OS,基于Ubuntu的Mint)上:使用apt-get install python3-tk(假定系统Python是3.x版本)。 对于2.x旧版系统,请改用apt-get install python-tk。 在某些情况下,可能需要指定次要版本,例如apt-get install python3.11-tk在某些情况下,自定义异常消息可能会提示安装python-tk,即使实际上应该安装python3-tk
对于Fedora,请使用dnf install python3-tkinter,如d-coder 此处所述
对于Arch,请使用pacman -S tk,如Jabba 此处所述
对于RHEL,请使用yum install python3-tkinter,如amzy-0 此处所述

Linux: 从源代码构建Python

上述软件包只能为系统中的Python(安装在/usr/bin目录下,由操作系统用于运行必要脚本)添加Tkinter支持。它们无法为从源代码构建的独立Python添加Tkinter支持。这是因为,在Python中使用Tkinter除了实际的Tcl/Tk库之外,还需要一个每次安装都会生成的“绑定”库(在Python源代码中称为_tkinter)。系统软件包不会将此库添加到其他Python安装中

因此,首先安装一个开发版的Tk软件包(例如apt-get install tk-dev),然后尝试重新构建。

另请参阅:

Brew(通常适用于MacOS)

使用brew install python-tk命令;如果需要,可以指定Python版本,例如:brew install python-tk@3.11

对于非系统安装,可能需要重新安装并指定Tkinter支持,例如:brew install python --with-tcl-tk。另请参阅:为什么通过Homebrew安装的Python不包含Tkinter

无头环境

一般来说,在像PythonAnywhereAmazon Linux EC2这样的无头服务器环境中,是不可能安装Tkinter或任何其他GUI工具包的。代码将在远程服务器上运行,因此没有显示GUI的监视器;虽然原则上代码可以发送命令回到客户端,然后客户端可以使用这些命令创建GUI,但通常情况下,服务器将不知道客户端的环境。使其正常工作需要预先设置某些通信协议(例如X11)。

虚拟环境

首先,修复虚拟环境所基于的安装。如果这不能解决问题,重新创建虚拟环境(并重新安装旧虚拟环境中安装的所有内容)。不幸的是,没有一个干净的解决方法。也许通过改变一堆符号链接来绕过问题是可能的,但这并不受支持。

如果无法修复基本安装(例如,由于系统上没有sudo权限),考虑安装单独的Python(例如,通过源代码编译),确保它安装了Tkinter支持,并从 Python创建虚拟环境。

Tkinter组件

一些用户会发现了解Tkinter系统包含的内容非常有用。有几个组件:

  • 底层的C语言编写的Tcl/Tk库。一些系统可能会独立安装Tcl/Tk,但默认情况下无法从Python中使用。

  • _tkinter实现模块,也是用C语言编写的,它在Python和Tcl/Tk之间提供接口("tkinter"意味着"Tk界面")。这是一个实现细节,不应该直接在Python用户代码中导入。(C代码可以追溯到1994年!)

  • tkinter包本身,它提供了对低级_tkinter接口的封装,以及ttk(用于新型“主题”小部件的单独接口)。

  • 更高级别的组件,例如IDLE和turtle

任何安装都可能理论上缺少这些组件中的任意一个或全部。对于 Linux 和 MacOS 上的 Python 系统安装,发行版维护者负责确保适当的软件包(例如 python3-tk)默认安装缺失的部分到适当的位置。

正如 Terry Jan Reedy 在 GitHub 上向我解释的那样:当 Windows 安装程序被告知要安装 Tcl/Tk 时,它将为该 Python 安装程序安装一个单独的库副本(以及相应的 _tkintertkinter 等)。在 Linux 上,Tcl/Tk 通常会随 Linux 一起提供;像 python3-tk 这样的软件包将添加使用系统 Tcl/Tk 的 _tkinter,以及一个 tkinter 软件包(自然会找到并使用 _tkinter 实现,使用正常的导入机制)。

由于在Windows上Tcl/Tk安装是“vendored”,因此Tcl/Tk版本将取决于Python版本。在Linux上,它将取决于系统,并且应该可以使用系统包管理器独立升级Tcl/Tk而不影响Python。特别注意的是,较新版本的Python可能无法与过时的系统Tcl/Tk配合使用。(要检查工作安装的Tcl/Tk版本,请参见如何确定我的Linux机器上安装了哪个版本的python3 tkinter?。)


2
希望这篇文章能够帮助像我一样使用venv并在同一个系统上同时拥有多个Python版本(例如3.8、3.9和3.10)的其他人。
假设您使用特定的Python版本创建了venv,但无法导入tkinter
$ python3.10 -m venv my_venv_1 #create a venv with python 3.10
$ source my_venv_1/bin/activate
$ python
Python 3.10.11 (main, Apr  5 2023, 14:15:10) [GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tkinter
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'tkinter'
>>> quit()
$ deactivate

您可以为与之前创建的venv的Python版本匹配的Python版本专门安装tkinter。例如,在Ubuntu上,您需要使用以下命令为现有的系统范围Python 3.10安装tkinter

sudo apt-get install python3.10-tk

现在,如果您激活了已经创建的venvtkinter将自动被捕获:

source my_venv_1/bin/activate
python
>>>import tkinter as tk
>>>

成功!


0

标准故障排除步骤

在得出需要安装Tkinter的结论之前,请确保以下内容。

  • 首先,使用Tkinter在这个程序中有意义吗?特别是对于Web应用程序和类似的客户端-服务器应用程序,通常不应该尝试在服务器上使用任何类型的桌面GUI工具包,包括Tkinter。服务器通常没有物理显示器,而且最终用户也无法看到它;大多数服务器托管“无头”服务器时不会包含Tkinter等Python支持。

    同样,通过这种方式“发送”GUI到客户端也通常没有意义。在Web应用程序中,数据(HTML/CSS/Javascript)将被发送到Web浏览器,在那里创建UI。对于将数据发送到服务器的独立程序,客户端应该实现GUI,并使用自己的逻辑来解释从服务器发送的数据以更新GUI小部件。服务器尝试“控制”客户端上的应用程序是没有意义的。

    特别注意Matplotlib和类似库:可能不需要使用特定的Tkinter来查看GUI结果,可能可以在没有GUI的情况下解决问题。特别是,可以告诉Matplotlib使用非GUI“后端”,然后将图形保存为图像文件而不是在屏幕上显示它们(这通常更有用)。还可以告诉它使用除Tkinter之外的其他GUI后端。有关详细信息,请参见:

  • 对于这个Python版本,import是否拼写正确?2.x代码默认必须引用Tkinter,但3.x必须引用tkinter

  • 正在使用哪个Python安装程序来运行代码?与运行错误的Python(即:为该Python安装了不兼容版本的第三方库)等其他问题一样,可能某些机器上的Python安装程序支持Tkinter,而其他安装程序则不支持

    特别注意,在Linux上,仅因为Tcl/Tk已安装在系统上并不意味着每个Python安装程序都可以访问它。需要将Tkinter支持添加到每个安装程序中。

    这可能会影响前面提到的问题:假设给定的机器安装了2.x和3.x版本。即使两者都可用Tkinter,尝试使用错误的版本运行代码也会导致ImportError(假设没有先出现SyntaxError,例如在3.x中尝试将print用作语句)。

    如果有意让某些Python安装程序在给定系统上不支持Tkinter,请确保Tkinter代码在支持Tkinter的安装程序上运行。

    特别要注意,虚拟环境算作单独的Python安装程序。通常,如果从具有Tkinter支持的基本安装程序创建了虚拟环境,则它们将具有Tkinter支持创建虚拟环境时。通常无法直接向虚拟环境添加Tkinter支持。请记住,


0

特殊环境

这是一个社区百科回答,旨在汇总处理非标准Python安装的方法。请编辑以添加相关信息。我先列出一些关于这些环境的之前的问题链接,无论它们是否得到了适当的回答。

Abaqus

python3-dbg(由gdb提供的调试版本)

QGIS

Enthought Canopy

Anaconda

PyPy

IronPython / Python.NET

使用PyInstaller等创建的捆绑可执行文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接