質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Q&A

解決済

2回答

10382閲覧

Python3 Tkinter exe化がうまくできない

person

総合スコア223

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

0グッド

0クリップ

投稿2020/04/15 07:35

編集2020/04/16 05:15

Windwosでpyinstallerを使ってexe化します。

Python

1import tkinter as tk 2 3win = tk.Tk() 4win.mainloop()

$ pyinstaller --noconsole test.py

でできました。(distフォルダにあるtest.exeでtkinterのウィンドウが表示されたことを確認)

しかし、複数のファイルから成っている(互いにimportしているファイル)ものをexe化しようとしたとき、それらのファイルにあるmain.pyを指定して

$ pyinstaller --noconsole main.py

と打ち、main.exeを起動すると

main.exe

このようなウィンドウが表示され、期待通りの動作になりません。
(exe化の動作は特にエラーはありません)

exe化の仕方が間違っているのでしょうか?

回答よろしくお願いします。

追記

ファイル構成

test
....├ main.py
....├ ○○.py
....├ △△.py
....└ ××.ini

pyinstallerコマンド実行ログ

>pyinstaller C:\Users\ユーザ名\Desktop\test\main.py 60 INFO: PyInstaller: 3.6 60 INFO: Python: 3.8.2 61 INFO: Platform: Windows-10-10.0.18362-SP0 63 INFO: wrote C:\Users\ユーザ名\Desktop\main.spec 65 INFO: UPX is not available. 66 INFO: Extending PYTHONPATH with paths ['C:\Users\ユーザ名\Desktop\test', 'C:\Users\ユーザ名\Desktop'] 66 INFO: checking Analysis 67 INFO: Building Analysis because Analysis-00.toc is non existent 67 INFO: Initializing module dependency graph... 69 INFO: Caching module graph hooks... 76 INFO: Analyzing base_library.zip ... 2499 INFO: Processing pre-find module path hook distutils 2499 INFO: distutils: retargeting to non-venv dir 'c:\users\ユーザ名\appdata\local\programs\python\python38-32\lib' 5228 INFO: Caching module dependency graph... 5362 INFO: running Analysis Analysis-00.toc 5365 INFO: Adding Microsoft.Windows.Common-Controls to dependent assemblies of final executable required by c:\users\ユーザ名\appdata\local\programs\python\python38-32\python.exe 5441 INFO: Analyzing C:\Users\ユーザ名\Desktop\test\main.py 5504 INFO: Processing module hooks... 5504 INFO: Loading module hook "hook-distutils.py"... 5506 INFO: Loading module hook "hook-encodings.py"... 5584 INFO: Loading module hook "hook-lib2to3.py"... 5588 INFO: Loading module hook "hook-pydoc.py"... 5589 INFO: Loading module hook "hook-sysconfig.py"... 5590 INFO: Loading module hook "hook-xml.etree.cElementTree.py"... 5591 INFO: Loading module hook "hook-xml.py"... 5642 INFO: Loading module hook "hook-_tkinter.py"... 5769 INFO: checking Tree 5770 INFO: Building Tree because Tree-00.toc is non existent 5771 INFO: Building Tree Tree-00.toc 5869 INFO: checking Tree 5869 INFO: Building Tree because Tree-01.toc is non existent 5871 INFO: Building Tree Tree-01.toc 5933 INFO: Looking for ctypes DLLs 5970 INFO: Analyzing run-time hooks ... 5975 INFO: Including run-time hook 'pyi_rth__tkinter.py' 5977 INFO: Including run-time hook 'pyi_rth_multiprocessing.py' 5986 INFO: Looking for dynamic libraries 6315 INFO: Looking for eggs 6315 INFO: Using Python library c:\users\ユーザ名\appdata\local\programs\python\python38-32\python38.dll 6316 INFO: Found binding redirects: [] 6327 INFO: Warnings written to C:\Users\ユーザ名\Desktop\build\main\warn-main.txt 6387 INFO: Graph cross-reference written to C:\Users\ユーザ名\Desktop\build\main\xref-main.html 6445 INFO: checking PYZ 6446 INFO: Building PYZ because PYZ-00.toc is non existent 6447 INFO: Building PYZ (ZlibArchive) C:\Users\ユーザ名\Desktop\build\main\PYZ-00.pyz 7148 INFO: Building PYZ (ZlibArchive) C:\Users\ユーザ名\Desktop\build\main\PYZ-00.pyz completed successfully. 7167 INFO: checking PKG 7167 INFO: Building PKG because PKG-00.toc is non existent 7168 INFO: Building PKG (CArchive) PKG-00.pkg 7187 INFO: Building PKG (CArchive) PKG-00.pkg completed successfully. 7195 INFO: Bootloader c:\users\ユーザ名\appdata\local\programs\python\python38-32\lib\site-packages\PyInstaller\bootloader\Windows-32bit\run.exe 7195 INFO: checking EXE 7198 INFO: Building EXE because EXE-00.toc is non existent 7199 INFO: Building EXE from EXE-00.toc 7199 INFO: Appending archive to EXE C:\Users\ユーザ名\Desktop\build\main\main.exe 7231 INFO: Building EXE from EXE-00.toc completed successfully. 7239 INFO: checking COLLECT 7239 INFO: Building COLLECT because COLLECT-00.toc is non existent 7240 INFO: Building COLLECT COLLECT-00.toc 9373 INFO: Building COLLECT COLLECT-00.toc completed successfully.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

teamikl

2020/04/15 08:46

--noconsole を外してビルドして見てください。 exeファイルを実行した時に、他のエラーログは見えますか?
teamikl

2020/04/16 05:33

これは pyinstaller を実行した時のログなので、 出来上がったexe ファイルを実行した時のログをお願いします。
person

2020/04/16 05:40

main.exeをコマンドプロンプトへドラッグアンドドロップしてEnterキーを押したところ File "configparser.py", line 960, in __getitem__ KeyError: 'setting' [19316] Failed to execute script main とありました。 iniファイルを読み込む際の ini = configparser.ConfigParser() ini.read(FILE, "UTF-8") 変数名 = ini["setting"]["OPTION1"] # ここを指しているようです。 exe化する前はエラーが発生している様子はなかったので気が付きませんでした・・・。 しかし、exe化してエラーが起こるということはこれではダメなのでしょうか?
teamikl

2020/04/16 05:59 編集

exe化によりファイルの場所が変わった等の影響だと思うので、 exe化自体がダメという事はないです。 読み込まれる設定ファイルの場所の確認 (実行方法によっては、カレントディレクトリの場所が変わるので注意) 何処のファイルが読まれてるのかを確認してください。 ファイルパスの指定ですが、 カレントディレクトリからの相対パスだったりしたら実行する場所によっては読み込めないので、 exe化する際は、exeファイルからのパスを指定したりします。 例) ini_path = os.path.join(os.path.dirname(sys.argv[0]), "config.ini")
person

2020/04/16 06:00

pyinstallerでオプションなしでexeファイルと同じディレクトリにiniファイルを入れたら実行できました。 しかし、--onefile オプションを付けると、同じようにiniファイルを置いても同じようなエラーが出ることを確認しました。
person

2020/04/16 06:16

ちなみにファイルの場所は import os FILE = os.path.dirname(__file__) + "/setting.ini" で指定しているため、ソースファイルと同じ位置に置けば問題ないと自分は思っています。
teamikl

2020/04/16 06:19

pyinstaller 等 exe 化する時は __file__ を使えなかったはずです。 実行環境によって変わる値なので
guest

回答2

0

ベストアンサー

こちらに書きますね。コメント欄より

python

1FILE = os.path.dirname(__file__) + "/setting.ini"

Pythonのexe化、Pyinstaller使用メモ

これに該当しそうです。

解消法: __file__ => sys.argv[0]

投稿2020/04/16 06:23

編集2020/04/16 06:24
teamikl

総合スコア8664

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

person

2020/04/16 06:32

そうでしたか。 sys.argv[0] でソースファイルの絶対パスを取得してから、ファイル名部分を除去するという処理に変えた方がいいということですか。 除去するには文字列操作を行う感じになりそうですね。
teamikl

2020/04/16 06:45

sys.argv[0] はソースではなく、実行ファイルのパスです。 (exe化した環境においては) pyinstaller が生成した exeファイルのパス。 今のコードで既にos.path.dirname でディレクトリ名を所得出来てますよ __file__ を sys.argv[0] に変えるだけで済むはずです。(必要に応じて import sys)
person

2020/04/16 06:47

こんな感じですかね。 もっとスマートなやり方もありそうですが・・・ import sys path = sys.argv[0] path_list = path.split("/") path_dir = "" for i in range(len(path_list) - 1): path_dir += path_list[i] + "/" path_dir = path_dir[:-1] # 最後の1文字除去(スラッシュで終わるため不要な場合は除去する) print(path_dir) # /Users/ユーザ名/Desktop
person

2020/04/16 06:50

あ、__file__をsys.argv[0]に置換すればいいんですね。 わかりました。 ありがとうございます。
teamikl

2020/04/16 06:50

コメント入れ違いになりましたね。以下で大丈夫なはずです path_dir = os.path.dirname(sys.argv[0]) ini_path = os.path.join(path_dir, "setting.ini")
guest

0

追記: 質問の更新より、以下の内容は外していたようです。このまま残しますが別で回答します。


以前の投稿からの推測になりますが、

仮に、この様なファイル・ディレクトリ構成で

- app - program2.py - program1.py - main.py
# main.py from app import program1 from app import program2
# app/program1.py from . import program2

とあった場合、pyinstaller で app\program1.py と指定しても
相対インポート部分がうまく機能しません。

python app/program1.py と実行した場合と同様でエラーになります。

python -m app.program1 では正常に起動できます。


回避策:

app (パッケージのディレクトリ(仮)) の外に exeファイルのエントリーポイントとなるような
スクリプトを作り、このファイルを pyinstaller で指定します。
(モジュールが正しくimport出来るようにPATHは調整してください)

python

1# run_app_program1.py 2 3import app.program1 4app.program1.main()

投稿2020/04/15 09:27

編集2020/04/16 06:13
teamikl

総合スコア8664

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問