【问题标题】:Unable to install tkinter with pyenv Pythons on MacOS无法在 MacOS 上使用 pyenv Python 安装 tkinter
【发布时间】:2020-06-13 14:08:58
【问题描述】:

通过pyenv安装的Python版本导入tkinter失败:

※ python
Python 3.8.1 (default, Feb 29 2020, 11:45:59)
[Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import tkinter
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/factor/.pyenv/versions/3.8.1/lib/python3.8/tkinter/__init__.py", line 36, in <module>
    import _tkinter # If this fails your Python may not be configured for Tk
ModuleNotFoundError: No module named '_tkinter'
>>>

或者您可能会收到有关标头版本与二进制文件不匹配的消息:

DEPRECATION WARNING: The system version of Tk is deprecated and may be removed in a future release. Please don't rely on it. Set TK_SILENCE_DEPRECATION=1 to suppress this warning.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/factor/.pyenv/versions/3.8.1/lib/python3.8/tkinter/__init__.py", line 4552, in _test
    root = Tk()
  File "/Users/factor/.pyenv/versions/3.8.1/lib/python3.8/tkinter/__init__.py", line 2263, in __init__
    self._loadtk()
  File "/Users/factor/.pyenv/versions/3.8.1/lib/python3.8/tkinter/__init__.py", line 2279, in _loadtk
    raise RuntimeError("tk.h version (%s) doesn't match libtk.a version (%s)"
RuntimeError: tk.h version (8.6) doesn't match libtk.a version (8.5)

【问题讨论】:

    标签: python macos tkinter pyenv


    【解决方案1】:

    TL;DR 设置环境。瓦尔斯。 tcl-tk 的警告 this GitHub comment 在通过 pyenv 安装新 Python 以获取 tkinter 时提到。

    首先,确保您通过自制软件获得最新的tcl-tk,然后注意它的警告:

    ※ brew install tcl-tk
    ※ brew info tcl-tk
    tcl-tk: stable 8.6.10 (bottled) [keg-only]
    ...
    ==> Caveats
    tcl-tk is keg-only, which means it was not symlinked into /usr/local,
    because tk installs some X11 headers and macOS provides an (older) Tcl/Tk.
    
    If you need to have tcl-tk first in your PATH run:
      echo 'export PATH="/usr/local/opt/tcl-tk/bin:$PATH"' >> ~/.zshrc
    
    For compilers to find tcl-tk you may need to set:
      export LDFLAGS="-L/usr/local/opt/tcl-tk/lib"
      export CPPFLAGS="-I/usr/local/opt/tcl-tk/include"
    
    For pkg-config to find tcl-tk you may need to set:
      export PKG_CONFIG_PATH="/usr/local/opt/tcl-tk/lib/pkgconfig"
    ...
    

    您还需要了解 pyenv 的 PYTHON_CONFIGURE_OPTS--with-tcltk-includes--with-tcltk-libs,例如来自this comment

    接下来,在激活环境变量的情况下重新安装 Python:

    ※ pyenv uninstall 3.8.1
    ※ env \
      PATH="$(brew --prefix tcl-tk)/bin:$PATH" \
      LDFLAGS="-L$(brew --prefix tcl-tk)/lib" \
      CPPFLAGS="-I$(brew --prefix tcl-tk)/include" \
      PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig" \
      CFLAGS="-I$(brew --prefix tcl-tk)/include" \
      PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I$(brew --prefix tcl-tk)/include' --with-tcltk-libs='-L$(brew --prefix tcl-tk)/lib -ltcl8.6 -ltk8.6'" \
      pyenv install 3.8.1
    

    现在应该可以工作了:

    ※ pyenv global 3.8.1
    ※ python
    Python 3.8.1 (default, Feb 29 2020, 11:56:10)
    [Clang 11.0.0 (clang-1100.0.33.17)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import tkinter
    >>> tkinter.TclVersion, tkinter.TkVersion
    (8.6, 8.6)
    >>> tkinter._test()
    # You should get a GUI
    

    如果您收到以下错误,您可能缺少 PYTHON_CONFIGURE_OPTS 环境。变种。以上。

    DEPRECATION WARNING: The system version of Tk is deprecated and may be removed in a future release. Please don't rely on it. Set TK_SILENCE_DEPRECATION=1 to suppress this warning.
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/Users/factor/.pyenv/versions/3.8.1/lib/python3.8/tkinter/__init__.py", line 4552, in _test
        root = Tk()
      File "/Users/factor/.pyenv/versions/3.8.1/lib/python3.8/tkinter/__init__.py", line 2263, in __init__
        self._loadtk()
      File "/Users/factor/.pyenv/versions/3.8.1/lib/python3.8/tkinter/__init__.py", line 2279, in _loadtk
        raise RuntimeError("tk.h version (%s) doesn't match libtk.a version (%s)"
    RuntimeError: tk.h version (8.6) doesn't match libtk.a version (8.5)
    

    【讨论】:

    • 作为记录,这在 Linux (Debian 10) 上也是开箱即用的。唯一不同的是brew info的输出有点不同。
    • 完成此操作后,我无法再安装python,它显示:BUILD FAILED (OS X 11.1 using python-build 20180424)
    • @BergP 您可能需要提供更多错误消息。我建议创建一个引用此答案的新问题。您可以从此答案链接到您的问题。
    【解决方案2】:

    如果您在 macOS 上使用pyenv 进行 Python 环境管理,这里是分步指南,以使 tkinter(和 IDLE)工作:

    1. 使用 Homebrew 安装 tcl-tk。在 shell 中运行 brew install tcl-tk
    2. 在shell中运行echo 'export PATH="/usr/local/opt/tcl-tk/bin:$PATH"' &gt;&gt; ~/.zshrc
    3. 通过退出Terminal 应用程序或运行source ~/.zshrc 重新加载shell
    4. 重新加载后检查tck-tk 是否在$PATH 中。运行echo $PATH | grep --color=auto tcl-tk。结果,您应该会看到您的 $PATH 内容,其中 tcl-tk 突出显示
    5. 现在我们从步骤 #1 的 Homebrew 输出中运行三个命令
      1. 在shell中运行export LDFLAGS="-L/usr/local/opt/tcl-tk/lib"
      2. 在shell中运行export CPPFLAGS="-I/usr/local/opt/tcl-tk/include"
      3. 在shell中运行export PKG_CONFIG_PATH="/usr/local/opt/tcl-tk/lib/pkgconfig"
    6. 如果你的 Python 版本已经用pyenv 安装,那么用pyenv uninstall &lt;your python version&gt; 卸载它。例如。 pyenv uninstall 3.8.2
    7. 设置python-build 将使用的环境变量。在 shell 中运行 PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I/usr/local/opt/tcl-tk/include' --with-tcltk-libs='-L/usr/local/opt/tcl-tk/lib -ltcl8.6 -ltk8.6'" 注意:将来使用与 Homebrew 一起实际安装的 tck-tk 版本。在发帖时8.6 是实际的
    8. 最终使用pyenvpyenv install &lt;version&gt; 安装Python。例如。 pyenv install 3.8.2

    测试

    1. 在shell中运行pyenv global &lt;verion that you've just installed&gt;
    2. 现在检查空闲。在 shell 中运行 idle。您应该会看到没有任何警告的 IDLE 窗口和“以红色打印的文本”。

    1. 现在检查tkinter。在 shell 中运行 python -m tkinter -c "tkinter._test()"。您应该会看到如图所示的测试窗口:

    就是这样!

    我的环境:

    检查执行上述步骤是否有问题:

    1. macOS 卡塔利娜
    2. zsh(包含在 macOS Catalina 中)= 上面的“shell”
    3. Homebrew(使用 Homebrew 官网的说明安装)
    4. pyenv(根据pyenv来自GitHub的官方自述文件更新了Homebrew和PATH)
    5. Python 3.8.x - 3.9.x(使用pyenv install &lt;version&gt; 命令安装)

    【讨论】:

    • 这很有帮助!我可以通过简单地使用env 方法以更少的步骤完成它(即,无需编辑 ~/.zshrc 来添加所有导出):env PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I/usr/local/opt/tcl-tk/include' --with-tcltk-libs='-L/usr/local/opt/tcl-tk/lib -ltcl8.6 -ltk8.6' --enable-shared" pyenv install 3.8.5 我添加了 --enable-shared 因为 PyInstaller 需要它。如果你不需要它:env PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I/usr/local/opt/tcl-tk/include' --with-tcltk-libs='-L/usr/local/opt/tcl-tk/lib -ltcl8.6 -ltk8.6'" pyenv install 3.8.5
    • 谢谢。这救了我的命。
    • 非常有趣。但足以让我思考“不”——我不会闲着。 Python 基础设施一团糟。
    • 我收到了与 Carl G 相同的错误消息。然后我尝试了这种方法,它对我有用。第7步是解决本帖问题的关键,这里需要在运行pyenv install 3.x.x之前指向python-build使用正确版本的tcl-tk@
    • 我在 M1 Mac 上试过这个,但不幸的是最后一步“pyenv install 3.x.x”(我在 3.7.9 的地方)给出了“BUILD FAILURE”。我想这是一些复杂的 M1 Mac 问题,我必须在 x86 模式下使用自制软件,但这很烦人......
    【解决方案3】:

    对于 MacOS Big Sur (11.2.3),Carl G 的回答对我不起作用,因为我遇到了 zlib 错误。在this answerthis blog post 的基础上,我发现了

    brew install bzip2
    export LDFLAGS="-L $(xcrun --show-sdk-path)/usr/lib -L brew --prefix bzip2/lib"
    export CFLAGS="-L $(xcrun --show-sdk-path)/usr/include -L brew --prefix bzip2/include"
    export PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I/usr/local/opt/tcl-tk/include' --with-tcltk-libs='-L/usr/local/opt/tcl-tk/lib -ltcl8.6 -ltk8.6' --enable-framework"
    pyenv install 3.8.6
    

    【讨论】:

      【解决方案4】:

      当我尝试通过 pyenv 安装 tkinter 时遇到了同样的问题。如果有人遇到同样的问题但仍想坚持使用pyenv,我可以使用以下方法修复它。

      修复

      1. 我按照@nickolay 的说明安装了tkinter 并设置了正确的路径。

      2. 然后,我使用pyenv install anaconda3-2020.07 命令安装了anaconda3-2020.07。

      3. 因为我使用的是 pyenv python 3.8.6 globally:我导航到我想使用 tkinter 的文件夹并使用 anaconda3-2020.07 locally 命令 @ 987654326@在该特定文件夹中使用此版本的 pyenv。它运行没有错误!

      注意:我在.bash_profile 中使用以下脚本来在cd 所需目录时自动触发virtualenv

      # manage python version using pyenv
      if command -v pyenv 1>/dev/null 2>&1; then
        eval "$(pyenv init -)"
      fi
      
      # add pyenv virtualenv
      eval "$(pyenv virtualenv-init -)"
      

      【讨论】:

        【解决方案5】:

        对于 Python 3.9 及以上版本,可以使用以下公式

        brew install python-tk@3.9

        它将安装 python@3.9 和 tcl-tk 并为您绑定它们。

        【讨论】:

        • 这在使用 pyenv 时没有帮助
        猜你喜欢
        • 1970-01-01
        • 2022-08-20
        • 2023-02-04
        • 2022-09-29
        • 2019-01-04
        • 2023-04-04
        • 2021-06-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多