Невозможно установить tkinter с pyenv Pythons на MacOS

Версии Python, установленные через pyenv, не импортируются 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)

7 ответов

TL;DR устанавливает env. вары. упомянутый вtcl-tkпредостережения и этот комментарий GitHub при установке новых Pythons через pyenv, чтобы получитьtkinter.

Во-первых, убедитесь, что у вас есть последняя tcl-tk через homebrew, а затем обратите внимание на его предостережения:

※ 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's PYTHON_CONFIGURE_OPTS, --with-tcltk-includes, а также --with-tcltk-libs, например, из этого комментария.

Затем переустановите 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окр. var. над.

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)

Вот пошаговое руководство, чтобы сделатьtkinter (и IDLE) работают, если вы используете pyenv для управления средами Python в macOS:

  1. установить tcl-tkс Homebrew. В оболочке запуститьbrew install tcl-tk
  2. в оболочке echo 'export PATH="/usr/local/opt/tcl-tk/bin:$PATH"' >> ~/.zshrc
  3. перезагрузить оболочку, выйдя Terminal приложение или запустить source ~/.zshrc
  4. после перезагрузки проверьте, что tck-tk в $PATH. Бегатьecho $PATH | grep --color=auto tcl-tk. В результате вы должны увидеть свое содержимое $PATH сtcl-tk выделил
  5. теперь мы запускаем три команды из вывода Homebrew с шага №1
    1. в оболочке export LDFLAGS="-L/usr/local/opt/tcl-tk/lib"
    2. в оболочке export CPPFLAGS="-I/usr/local/opt/tcl-tk/include"
    3. в оболочке export PKG_CONFIG_PATH="/usr/local/opt/tcl-tk/lib/pkgconfig"
  6. если у вас уже установлена ​​версия Python с pyenv затем удалите его с помощью pyenv uninstall <your python version>. Напримерpyenv uninstall 3.8.2
  7. установить переменную среды, которая будет использоваться python-build. В оболочке запустить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'" Примечание: в будущем использовать tck-tkверсия, которая фактически была установлена ​​с Homebrew. В момент публикации8.6 был фактическим
  8. наконец установите Python с pyenv с участием pyenv install <version>. Напримерpyenv install 3.8.2

Контрольная работа

  1. в оболочке pyenv global <verion that you've just installed>
  2. теперь проверьте IDLE. В оболочке запуститьidle. Вы должны увидеть окно IDLE без предупреждений и "текста, напечатанного красным".

  1. теперь проверьте tkinter. В оболочке запуститьpython -m tkinter -c "tkinter._test()". Вы должны увидеть тестовое окно, как на картинке:

Это оно!

Моя среда:

проверьте, что что-то пошло не так, выполнив шаги выше:

  1. macOS Catalina
  2. zsh(входит в состав macOS Catalina) = "оболочка" выше
  3. Homebrew (устанавливается по инструкции с официального сайта Homebrew)
  4. pyenv (установлен с Homebrew и PATH обновлен в соответствии с pyenv официальный файл readme с GitHub)
  5. Python 3.8.x - 3.9.x (установлен с pyenv install <version> команда)

На момент написания этой статьи кажется, чтоtcl-tkбольше не предназначен только для бочонков, и, следовательно, установка переменных среды больше не требуется:

      ※ brew info tcl-tk
==> tcl-tk: stable 8.6.13 (bottled)
...
==> Caveats
The sqlite3_analyzer binary is in the `sqlite-analyzer` formula.
==> Analytics
...

Действительно, я смог предоставитьpyenvсtkinterи решить проблему с плакатом, просто запустив:

      ※ pyenv uninstall <python version>
※ brew install tcl-tk
※ pyenv install <python version>

(Кстати, я использую MacOS Ventura на кремниевом процессоре Apple.)

Кажется, есть проблема с параметрами Xcode, zlib и компилятора. Из brew они сделали несколько патчей до версии Python 3.8.0.

Моя конфигурация

      $ sw_vers
ProductName:    macOS
ProductVersion: 11.2.3
BuildVersion:   20D91
      $ clang --version
Apple clang version 12.0.0 (clang-1200.0.32.29)
Target: x86_64-apple-darwin20.3.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

Это сработало для меня, чтобы установить 3.8.0 и 3.9.0

      
# Resinstall Xcode
sudo rm -rf /Library/Developer/CommandLineTools
xcode-select --install

# Install zlib and bzip2 using brew
brew reinstall zlib bzip2
 
# Install tcl-tk tkinter
brew install tcl-tk

# Uninstall previous versions from python
pyenv uninstall 3.8.0
pyenv uninstall 3.9.0

env \
  PATH="$(brew --prefix tcl-tk)/bin:$PATH" \
  LDFLAGS="-L$(brew --prefix tcl-tk)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix bzip2)/lib" \
  CPPFLAGS="-I$(brew --prefix tcl-tk)/include -L$(brew --prefix zlib)/include -L$(brew --prefix bzip2)/include" \
  PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig" \
  CFLAGS="-I$(brew --prefix tcl-tk)/include -I$(brew --prefix openssl)/include -I$(brew --prefix bzip2)/include -I$(brew --prefix zlib)/include -I$(brew --prefix readline)/include -I$(xcrun --show-sdk-path)/usr/include" \
  LDFLAGS="-I$(brew --prefix tcl-tk)/lib -L$(brew --prefix openssl)/lib -L$(brew --prefix readline)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix bzip2)/lib"
  pyenv install --patch 3.8.3 < <(curl -sSL https://github.com/python/cpython/commit/8ea6353.patch\?full_index\=1)
  
env \
  PATH="$(brew --prefix tcl-tk)/bin:$PATH" \
  LDFLAGS="-L$(brew --prefix tcl-tk)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix bzip2)/lib" \
  CPPFLAGS="-I$(brew --prefix tcl-tk)/include -L$(brew --prefix zlib)/include -L$(brew --prefix bzip2)/include" \
  PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig" \
  CFLAGS="-I$(brew --prefix tcl-tk)/include -I$(brew --prefix openssl)/include -I$(brew --prefix bzip2)/include -I$(brew --prefix zlib)/include -I$(brew --prefix readline)/include -I$(xcrun --show-sdk-path)/usr/include" \
  LDFLAGS="-I$(brew --prefix tcl-tk)/lib -L$(brew --prefix openssl)/lib -L$(brew --prefix readline)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix bzip2)/lib"
  pyenv install 3.9.0

Мои источники:

Для MacOS Big Sur (11.2.3) ответ Карла Джи не сработал для меня, потому что у меня возникла ошибка zlib. Основываясь на этом ответе и этом сообщении в блоге , я добился успеха с

      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

У меня была такая же проблема, когда я пытался установить через pyenv. Я смог исправить это, используя следующее, на случай, если у кого-то такая же проблема, и он все еще хочет придерживаться pyenv.

Исправление

  1. Я выполнил инструкции @nickolay по установке tkinter и задайте путь правильным путем.

  2. Затем я установил anaconda3-2020.07 с помощью pyenv install anaconda3-2020.07 команда.

  3. Поскольку я использую pyenv python 3.8.6 глобально : я перешел в папку, в которой хочу использовать tkinter, и использовал anaconda3-2020.07 локально с помощью команды pyenv local anaconda3-2020.07чтобы использовать эту версию pyenv в этой конкретной папке. Все прошло без ошибок!

Примечание. Я использую следующий сценарий в .bash_profile для автоматического запуска virtualenv, когда cd желаемый каталог

      # 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 -)"

Для версии Python 3.9 и выше вы можете использовать следующую формулу

варить установить python-tk@3.9

Он установит python@3.9 и tcl-tk и свяжет их за вас.

Другие вопросы по тегам