Невозможно установить tkinter с pyenv Pythons на MacOS - PullRequest
2 голосов
/ 29 февраля 2020

Версии 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)

1 Ответ

5 голосов
/ 29 февраля 2020

TL; DR установить env. вары. упоминается в предостережениях tcl-tk и в этом комментарии GitHub при установке новых питонов через 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"
...

Вам также нужно будет знать о PYTHON_CONFIGURE_OPTS, --with-tcltk-includes и --with-tcltk-libs pyenv, например, из этого комментария .

Далее переустановите 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 env. вар. выше.

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)
...