LoginSignup
1

More than 3 years have passed since last update.

cx_Freeze 用の tkinter 設定を動的に実施する

Last updated at Posted at 2019-02-19

cx_Freeze で tkinter を使うコードをビルドすると,
1. TK_LIBRARY, TCL_LIBRARY の環境変数がセットされていない
2. tk86t.dll tcl86.dll がコピーされない
といった諸々の面倒に出会います.

いろいろなところで解決策が提示されているのですが, アドホックな話が多く, 例えば venv の中できちんと動かすには? といった事例はあまりないように思えます.

ということで取りあえず cx_Freeze 用の setup.py の中で, 上記の 1, 2 を解決するスケルトンです.
(python 3.7 で動作確認)

参考資料は
- https://stackoverflow.com/questions/34939356/python-pygame-exe-build-with-cx-freeze-tcl-library-error
- https://stackoverflow.com/questions/43464355/how-to-find-the-path-of-tcl-tk-library-that-tkinter-is-currently-using
- https://qiita.com/sta/items/b360c5fb61ae2d22b321

import sys
import os
import pathlib

# set {TCL,TK}_LIBRARY environment variable
import tkinter
root = tkinter.Tk()
tcl_library_path = pathlib.Path(root.tk.exprstring('$tcl_library'))
tk_library_path = pathlib.Path(root.tk.exprstring('$tk_library'))
os.environ['TCL_LIBRARY'] = str(tcl_library_path)
os.environ['TK_LIBRARY'] = str(tk_library_path)

# find tk86t.dll and tcl86t.dll
tcltk_search_dll = {'tk86t.dll', 'tcl86t.dll'}
tcltk_found_dll = {}

for p in sys.path:
    p = pathlib.Path(p)
    for f in p.glob('*'):
        if f.is_file():
            f_low = f.name.lower()
            if f_low in tcltk_search_dll:
                tcltk_found_dll[f_low] = str(f)
                tcltk_search_dll.remove(f_low)

                if not tcltk_search_dll:
                    break
    else:
        continue
    break

if tcltk_search_dll:
    raise 'cannot find tcl/tk DLL. ' + str(tcltk_search_dll)
print('tcl/tk DLL:', tcltk_found_dll)

tcltk_include_files = [(v, 'lib/'+k) for k, v in tcltk_found_dll.items()]

from cx_Freeze import setup, Executable

buildOptions = dict(
    packages = [],
    excludes = [],
    include_files = tcltk_include_files)

base = 'Console'

executables = [
    Executable('myprog.py', base=base)
]

setup(name='myproj',
      version = '1.0',
      description = 'my project',
      options = dict(build_exe = buildOptions),
      executables = executables)

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1