75

Versions of Python installed via pyenv fail to import 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'
>>>

Or you might get a message about the header version doesn't match the binary:

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
  • For an in-depth explanation of how system and non-system Pythons interact with tkinter and why this issue occurs, see this answer. Commented May 4, 2023 at 4:40

8 Answers 8

137

TL;DR set the environment variables mentioned in tcl-tk's caveats and this GitHub comment when installing new Python interpreters via pyenv to get tkinter.

First, ensure you have the latest tcl-tk via Homebrew and then pay attention to its caveats:

※ 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"
...

You'll also need to know about pyenv's PYTHON_CONFIGURE_OPTS, --with-tcltk-includes, and --with-tcltk-libs, e.g. from this comment.

Next, reinstall Python with the environment variables active:

※ 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

It should work now:

※ 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

If you get the following error, you might be missing the PYTHON_CONFIGURE_OPTS environment variable above.

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)
Sign up to request clarification or add additional context in comments.

4 Comments

For the record this worked out-of-the-box on Linux (Debian 10) as well. The only difference is that the output of brew info was a bit different.
after I did this, I cannot install python anymore, it shows: BUILD FAILED (OS X 11.1 using python-build 20180424)
@BergP you will probably need to provide more of the error message. I would recommend creating a new question that references this answer. You can link to your question from this answer.
What saved me was installing the tk-devel package. I already had python3-tkinter installed but it wasn't enough. After installing the tk-devel package I could successfully install python version via pyenv install <version> command without errors.
57

Here is step-by-step guide to make tkinter (and IDLE) work if you use pyenv for Python environments management on macOS:

  1. install tcl-tk with Homebrew. In a shell, run brew install tcl-tk

  2. in the shell, run echo 'export PATH="/usr/local/opt/tcl-tk/bin:$PATH"' >> ~/.zshrc

  3. reload the shell by quitting the Terminal application or run source ~/.zshrc

  4. after it is reloaded, check that tcl-tk is in $PATH. Run echo $PATH | grep --color=auto tcl-tk. As the result, you should see your $PATH contents with tcl-tk highlighted

  5. now we run three commands from Homebrew's output from step #1

    1. in the shell, run export LDFLAGS="-L/usr/local/opt/tcl-tk/lib"
    2. in the shell, run export CPPFLAGS="-I/usr/local/opt/tcl-tk/include"
    3. in the shell, run export PKG_CONFIG_PATH="/usr/local/opt/tcl-tk/lib/pkgconfig"
  6. if you have your Python version already installed with pyenv, then uninstall it with pyenv uninstall <your python version>. E.g., pyenv uninstall 3.8.2

  7. set the environment variable that will be used by python-build. In the shell, run 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'"

    Note: in the future, use the tck-tk version that actually installed with Homebrew. At the moment of posting, 8.6 was the actual version

  8. finally, install Python with pyenv with pyenv install <version>. E.g., pyenv install 3.8.2

Test

  1. in the shell, run pyenv global <verion that you've just installed>

  2. now check IDLE. In the shell, run idle. You should see the IDLE window without any warnings and "text printed in red".

    IDLE window run from Terminal. No warnings

  3. now check tkinter. In the shell, run python -m tkinter -c "tkinter._test()". You should see a test window like on the image:

    Tkinter test window

That's it!

My environment:

Check this if something went wrong executing the steps above:

  1. macOS v10.15 (Catalina)
  2. Z shell, executable zsh (included in macOS Catalina) = "shell" above
  3. Homebrew (installed with instructions from the Homebrew official website)
  4. pyenv (installed with Homebrew and PATH updated according to the pyenv official README from GitHub)
  5. Python 3.8.x - 3.9.x (installed with pyenv install <version> command)

5 Comments

This was very helpful! I was able to do it in fewer steps by simply using the env approach (i.e., no need to edit ~/.zshrc to add all the exports): 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 I added --enable-shared since PyInstaller needs it. If you don't need it: 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
Very interesting. But enough there for me to think "nope" - I'll do without idle. Python infrastructure is a complete and utter mess.
I got the same error message as Carl G. Then I tried this method and it works for me. The step 7 is the key to solve the problem in this post, where you need to point python-build to use the correct version of tcl-tk before you run pyenv install 3.x.x
I tried this on an M1 Mac, but unfortunately the last step "pyenv install 3.x.x" (where I did 3.7.9) gives a "BUILD FAILURE". I guess it's some complicated M1 Mac issue and I'll have to use home-brew in x86 mode but that's annoying...
For those using asdf in place of pyenv above, I recently upgraded asdf via homebrew to v0.10.2 and it broke all file paths within /Users/<my user>/.asdf/shims/*. I had to manually open each file under this directory and replace the /0.10.1/ in the file path with /0.10.2/. Not sure why this happened...
15

At the time of this writing, it appears that tcl-tk is no longer keg-only and, therefore, setting environment variables is no longer needed:

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

Indeed, I was able to provide pyenv with tkinter and solve the poster's problem simply by running:

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

(FWIW, I am using macOS v13 (Ventura) on an Apple silicon processor.)

6 Comments

On an Apple M1 in 2023, this seems to be the best way to fix this!
I also confirm that this works flawlessly on MacOs Ventura. The other methods are overcomplicating everything and I'm glad that I scrolled enough in order to find a better approach.
I wasn't able to get this to work on macOS Sonoma. Still get the error ModuleNotFoundError: No module named '_tkinter'
@Ben - on macOS Sonoma as well, and this did not work for me either. I then also tried setting various environment variables as described in other answers. That also did not work. Running on an M1 Mac.
This worked on Mac Studio with: - Sonoma 14.7, - Homebrew 4.4.5 - Pyenv version of Python 3.13.0 (had to be reinstalled after installing tcl-tk). NOTE: If you do brew install [email protected] (latest at the time of writing - Nov 2024), you will also get latest tcl-tk package as a dependency installed. I only had to re-install Python version 3.13.0 after that with pyenv and pyenv install 3.13.0 picked up this (from logs): python-build: use tcl-tk from homebrew
|
1

For macOS v11.2.3 (Big Sur), Carl G's answer didn't work for me, because I got a zlib error. Building off of this answer and this blog post, I found success with

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

Comments

0

I had the same issue when I tried to install tkinter through pyenv. I was able to fix it using the following in case someone has the same problem and still want to stick with pyenv.

The Fix

  1. I followed @nickolay instructions to install tkinter and set the path the proper way.

  2. Then, I installed anaconda3-2020.07 using the pyenv install anaconda3-2020.07 command.

  3. Because I am using pyenv python 3.8.6 globally: I navigated to the folder I want to use tkinter and used the anaconda3-2020.07 locally by utilizing the command pyenv local anaconda3-2020.07to use this version of pyenv in that specific folder. It ran without errors!

Note: I am using the following script in the .bash_profile to trigger the virtualenv automatically when cd the desired directory

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

Comments

0

To expand on the answer provided by Carl G for the Fish shell and/or Poetry users and assuming Homebrew (executable brew) users.

To make sure you can use your chosen Python version:

brew upgrade pyenv

Set the correct shell variable for Fish shell users:

# Fish specific
set PATH "$(brew --prefix tcl-tk)/bin:$PATH"
set LDFLAGS "-L$(brew --prefix tcl-tk)/lib"
set CPPFLAGS "-I$(brew --prefix tcl-tk)/include"
set PKG_CONFIG_PATH "$(brew --prefix tcl-tk)/lib/pkgconfig"
set CFLAGS "-I$(brew --prefix tcl-tk)/include"
set 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'"

In the same shell session, install your Python version

pyenv install 3.12.6

Make it the default Python installation:

pyenv global 3.12.6

However, I had some Homebrew Python version at /opt/homebrew/opt/[email protected]/Frameworks/Python.framework/Versions/3.12 which Poetry did keep using even setting pyenv global, so to force the newly compiled python version:

Remove the current associated venv associated with the Poetry project

poetry env remove --all

Get pyenv Python path:

pyenv which python
# /Users/hayer/.pyenv/versions/3.12.6/bin/python

Use the path as the argument for Poetry:

poetry env use /Users/hayer/.pyenv/versions/3.12.6/bin/python

To test your Python installation:

poetry shell
# Spawns new shell with Python activated
# Start a Python session
python
# Python 3.12.6
import tkinter
# Should not result in errors

For UV users

At the moment of writing, it is not possible to compile Python with other settings or that UV provides workable tkinter out of the box. See this GitHub Issue.

Comments

0

In my case, no options worked (macOS v15.3.x (Sequoia), Homebrew-ed Python 3.13.x, pyenv with v3.8, 3.9, 3.11, etc.) - uninstalling pyenv, compiling the versions with LDFLAGS, CFLAGS, etc.

What did help was the "nuke them all" solution, clean and reinstall everything:

brew uninstall pyenv
brew uninstall python-tk
brew uninstall python  # You will most likely need:
# brew uninstall --ignore-dependencies python     # , because most likely there are other packages that depend on it
brew install tcl-tk    # if not done before
brew install python
brew install python-tk
brew install pyenv

Comments

-1

For Python 3.9 and above versions, you can use the following formula:

brew install [email protected]

It will instal [email protected] and tcl-tk and bind them for you.

1 Comment

This doesn't help when using pyenv

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.