Python + Kivy + Pyinstallerでexeファイルを作成したいです。  
以前使用していたPCでは問題なく`pyinstaller
--onedir`オプションでexeファイルを生成できていたのですが、PCを買い替えて環境構築をし直したら以前のコマンドが動作しなくなりました。

使用環境は以下の通りです。  
・Anaconda Navigator 2.2.0  
・Pyinstaller 5.1  
・Python 3.912  
・Windows11 64bit

以下が使用したPythonファイルです。  
`python main.py`を実行すると、Kivyでシンプルなアプリが起動します。

**main.py**

```

    #-*- coding: utf-8 -*-
    
    from kivy.lang import Builder
    Builder.load_string("""
    <TextWidget>:
        BoxLayout:
            orientation: 'vertical'
            size: root.size
    
            TextInput:
                text: root.text
    
            Button:
                id: button1
                text: "OK"
                font_size: 48
                on_press: root.buttonClicked()
    """)
    
    from kivy.app import App
    from kivy.uix.widget import Widget
    
    from kivy.properties import StringProperty 
    
    class TextWidget(Widget):
        text = StringProperty()
    
        def __init__(self, **kwargs):
            super(TextWidget, self).__init__(**kwargs)
            self.text = ''
    
        def buttonClicked(self):
            for i in range(5):
                self.text += str(i) + '\n'
    
    class TestApp(App):
        def __init__(self, **kwargs):
            super(TestApp, self).__init__(**kwargs)
            self.title = 'greeting'
    
        def build(self):
            return TextWidget()
    
    if __name__ == '__main__':
        TestApp().run()
    
```

**\--onefileオプションと、--onedirオプションの比較**

ネット上の記事では、`--onefile`オプションを使用した例ばかりが紹介されていたため、`--onedir`オプションの使い方が分からず困っています。

`--onefile`オプションでexeファイルを作成するより、`--onedir`オプションで作成したほうがexeファイルの起動時間が早いため、`--onedir`オプションを使いたいです。

**1\. --onefileオプションを使用した場合**

`--onefile`オプションを使用した場合は、問題なく動作をします。  
まず以下のコマンドを実行します。

```

    pyinstaller main.py --onefile
    
```

そして、生成されたmain.specファイルを以下のように編集しました。

**-onefileオプションを使用した場合のmain.spec**

```

    # -*- mode: python ; coding: utf-8 -*-
    
    from kivy_deps import sdl2, glew
    block_cipher = None
    
    
    a = Analysis(['main.py'],
                 pathex=[],
                 binaries=[],
                 datas=[],
                 hiddenimports=['win32file', 'win32timezone'],
                 hookspath=[],
                 hooksconfig={},
                 runtime_hooks=[],
                 excludes=[],
                 win_no_prefer_redirects=False,
                 win_private_assemblies=False,
                 cipher=block_cipher,
                 noarchive=False)
    pyz = PYZ(a.pure, a.zipped_data,
                 cipher=block_cipher)
    
    exe = EXE(pyz,
              a.scripts,
              a.binaries,
              a.zipfiles,
              a.datas,  
              *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
              name='main',
              debug=False,
              bootloader_ignore_signals=False,
              strip=False,
              upx=True,
              upx_exclude=[],
              runtime_tmpdir=None,
              console=True,
              disable_windowed_traceback=False,
              target_arch=None,
              codesign_identity=None,
              entitlements_file=None )
    coll = COLLECT(exe, Tree('.'),
                   a.binaries,
                   a.zipfiles,
                   a.datas,
                   *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
                   strip=False,
                   upx=True,
                   name='main')
    
```

次の、以下のコマンドでexeファイルを作成しました。

```

    pyinstaller main.spec
    
```

すると、問題なく`dist/main/main.exe`ファイルをダブルクリックで実行できました。  
しかし、この時点で少しおかしい気がするのですが、-onefileオプションを使用すると、dist直下に`main.exe`があり、`dist/main/main.exe`にもexeファイルがあります。

本来、`--onedir`オプションを使わないと`dist/main`フォルダは作られなかったように記憶しているのですが、仕様が変わったのでしょうか？

また、`--onefile`オプションで生成した`dist/main/main.exe`を取り出して他のフォルダに移しても単体で起動してしまうようです。

[![画像の説明をここに入力](https://i.stack.imgur.com/fr3WK.png)](https://i.stack.imgur.com/fr3WK.png)

**2\. --onedirオプションを使用した場合**

ファイルを1つにまとめたくないので、以下のように--
onedirオプションを付けて実行しました。実行前に、`--onefile`オプションで生成された`build`や`dist`のフォルダは削除済です。

```

    pyinstaller main.py --onedir
    
```

生成されたmain.specを編集して以下のようにしました。

**-onedirオプションを使用した場合のmain.spec**

```

    # -*- mode: python ; coding: utf-8 -*-
    from kivy_deps import sdl2, glew
    
    block_cipher = None
    
    
    a = Analysis(['main.py'],
                 pathex=[],
                 binaries=[],
                 datas=[],
                 hiddenimports=['win32file', 'win32timezone'],
                 hookspath=[],
                 hooksconfig={},
                 runtime_hooks=[],
                 excludes=[],
                 win_no_prefer_redirects=False,
                 win_private_assemblies=False,
                 cipher=block_cipher,
                 noarchive=False)
    pyz = PYZ(a.pure, a.zipped_data,
                 cipher=block_cipher)
    
    exe = EXE(pyz,
              a.scripts, 
              *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
              exclude_binaries=True,
              name='main',
              debug=False,
              bootloader_ignore_signals=False,
              strip=False,
              upx=True,
              console=True,
              disable_windowed_traceback=False,
              target_arch=None,
              codesign_identity=None,
              entitlements_file=None )
    coll = COLLECT(exe, Tree('.'),
                   a.binaries,
                   a.zipfiles,
                   a.datas,
                   *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
                   strip=False,
                   upx=True,
                   name='main')
    
```

その後、以下のコマンドを実行しました。

```

    pyinstaller main.spec
    
```

`dist/main/main.exe`を実行してもソフトウェアが起動しません。  
`main.spec`ファイルの編集の仕方などが間違っているのでしょうか？

【追記】  
`--onedir`オプションで生成された`main.exe`も、`--onefile`オプションで生成された`main.exe`もそのままでは実行できなかったため`main.spec`ファイルを編集したあとに実行しています。

`--onefile`オプションの場合は、`main.spec`を編集すれば動作したのですが、`--onedir`オプションの場合は`main.spec`を編集しても動作しませんでした。

`--onefile`オプション時の`main.spec`の編集方法は以下の記事を参考にしました。  
[kivyで作ったアプリケーションをPyinstallerを使ってEXEファイル化する方法](https://senablog.com/python-
kivy-pyinstaller/)

`--onedir`オプションの場合も`--onefile`オプションと同じ内容を参考にして編集したので、それが動作しない原因かもしれません。

以前使用していたWindows10のマシンでは、specファイルを使わずにコマンドを実行しても動作する`main.exe`ファイルが生成できていたので、今の環境に依存したエラーの可能性もありえます。
CC BY-SA 4.0
2022-07-01T23:41:01.777
89717
2022-07-03T11:27:49.753
2022-07-02T10:15:21.737
36446
36446
question
python pyinstaller kivy
PyInstallerで「--onedir」オプションの使い方がわからない
**1\. --onefileオプションを使用した場合**

「--onefileオプションを使用すると、dist直下にmain.exeがあり、dist/main/main.exeにもexeファイルがあります。」について

**\--onefileオプションを使用した場合のmain.spec** を編集した際に、`coll =
COLLECT(...)`のセクションまで書き加えてしまったことが原因でしょう。

つまりオプションの使い方では無く、`.spec`ファイルの編集内容の問題と考えられます。

ドキュメントのこの部分が該当するでしょう。  
[Spec File Operation](https://pyinstaller.org/en/stable/spec-files.html#spec-
file-operation)

>   * An instance of COLLECT creates the output folder from all the other
> parts.
>

>
> In one-file mode, there is no call to COLLECT, and the EXE instance receives
> all of the scripts, modules and binaries.

>   * COLLECTのインスタンスは、他のすべての部分から出力フォルダーを作成します。
>

>
> 1ファイルモードでは、COLLECTの呼び出しはなく、EXEインスタンスはすべてのスクリプト、モジュール、およびバイナリを受け取ります。

それぞれのオプションを使って実行ファイルを作った際に自動的に作成される、編集前の`.spec`ファイルの内容を比べてみれば、`coll =
COLLECT(...)`のセクションの有無が分かります。

**2\. --onedirオプションを使用した場合**

> `dist/main/main.exe`を実行してもソフトウェアが起動しません。  
>  `main.spec`ファイルの編集の仕方などが間違っているのでしょうか？

おそらくそうでしょう。  
`--onedir`オプションを指定した際に自動的に作成される、編集前の`.spec`ファイルで一度実行ファイルを作って何かしら起動する/あるいはエラーが発生するのが判ってから、編集していけば良いと思われます。

質問に提示されたソースコードから作成した実行ファイルは`.spec`ファイルを編集せずとも動作しました。  
質問者さんの実際のプログラムでは、それに応じた編集が必要となるでしょうが、その詳細はおそらく提示されたソースコードには表れていないでしょうから、質問者さん自身で調べる必要があるでしょう。

* * *

コメントによるとAnacondaをアンインストールしてWinPythonをベースに環境構築したらデフォルトの使い方で動作したとのこと。  
Anaconda環境の何かが影響して問題が発生していたということでしょう。

参考:  
[【WinPython】使い方・設定まとめ](https://algorithm.joho.info/programming/python/winpython/)  
[WinPython](https://sourceforge.net/projects/winpython/)  
[Windows + WinPython + pipの場合 -
【Python】Kivyをインストールする方法(pip編)](https://algorithm.joho.info/programming/python/kivy-
install/#toc2)
CC BY-SA 4.0
2022-07-02T08:43:49.397
89722
2022-07-03T11:27:49.753
2022-07-03T11:27:49.753
26370
26370
89717
answer