web-dev-qa-db-ja.com

Kivy:単一の実行可能ファイルにコンパイルする

Kivyフォーラムで回答が得られなかったので、ここで試してみてください。

チュートリアルのpongコードを1つのファイルの実行可能ファイルとしてコンパイルする場合でも、実行するには、同じフォルダーにpong.kvファイルを含める必要があります。そうしないと、exeを起動したときに次のエラーが発生します。

 
 GL:EXT_framebuffer_objectがサポートされています
 [INFO] [GL] OpenGLバージョン
 [INFO] [GL] OpenGLベンダー
 [INFO] [ GL] OpenGLレンダラー
 [INFO] [GL] OpenGL解析バージョン:2、1 
 [INFO] [GL]シェーディングバージョン
 [INFO] [GL]テクスチャ最大サイズ
 [INFO] [GL]テクスチャ最大単位
 [INFO] [ウィンドウ]自動追加sdl2入力プロバイダー
 [INFO] [ウィンドウ]仮想キーボードは許可されていません。
ドッキングされていないシングルモード
トレースバック(最後の最後の呼び出し):
ファイル ""、行81、
ファイル "c:\ python34\lib\site-packages\kivy\app.py "、802行目、in 
 run 
 root = self.build()
ファイル" "、75行目、ビルド
ファイル" " 、20行目、serveB all 
 AttributeError: 'NoneType'オブジェクトに属性がありません 'center' 
 mainが-1 
 
を返しました

どうすれば1つの実行可能ファイルとして実行できますか。これが私のpong.specファイルです:



    # -*- mode: python -*-

    from kivy.deps import sdl2, glew

    block_cipher = None


    a = Analysis(['Code\main.py'],
                 pathex=['E:\\Development\\Pong'],
                 binaries=None,
                 datas=None,
                 hiddenimports=[],
                 hookspath=[],
                 runtime_hooks=[],
                 excludes=[],
                 win_no_prefer_redirects=False,
                 win_private_assemblies=False,
                 cipher=block_cipher)
    pyz = PYZ(a.pure, a.zipped_data,
                 cipher=block_cipher)

    a.datas += [('Code\pong.kv', 'E:\\Development\\Pong\Code\pong.kv', 'DATA')] 

    exe = EXE(pyz,Tree('Code'),
              a.scripts,
              a.binaries,
              a.zipfiles,
              a.datas,
              *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
              name='pong',
              debug=False,
              strip=False,
              upx=True,
              console=True , icon='pong.ico')

データリストにpong.kvを含めようとしましたが、それは役に立ちませんでした。

ありがとう、-Raj

9
Raj

KeyWeeUsrによって提供されるリンクに基づく( PyInstallerでデータファイルをバンドルする および PyInstallerを使用してPythonスクリプト からEXEを作成する)) Kivyのリソースパスメソッド、これが実行可能なソリューションです。SYS._MEIPASS(パブリックAPIが望ましい)を使用し、Python)にコードスニペットを追加する必要があるため、エッジが少し荒いように感じます=コード。ただし、ソリューションはWindowsとMacの両方で機能するため、共有します。

次のコード階層があると仮定します。

 MyCode /
 MyApp.py(これはメインプログラムです)
 myapp.kv(これは関連するkvファイルです)
 
 MyData/(これは、アプリが使用するデータの場所です)
 myapp.icns(例:macのアイコンファイル)
 myapp.ico(例:windowsのアイコンファイル)
 
ビルド/
mac/
myapp.spec(macプラットフォームでビルドするスペックファイル)
 pc /
myapp.spec(Windowsでビルドするスペックファイルプラットフォーム)
 
 MyHiddenImports /(python非表示のインポート用のファイルを含む)

コードが実行時にpythonコードを含む別のフォルダーもsys.pathに追加する場合に備えて、MyHiddenImportsフォルダーを例に追加しました。

MyApp.pyに以下を追加します。

def resourcePath():
    '''Returns path containing content - either locally or in pyinstaller tmp file'''
    if hasattr(sys, '_MEIPASS'):
        return os.path.join(sys._MEIPASS)

    return os.path.join(os.path.abspath("."))

if __name__ == '__main__':
    kivy.resources.resource_add_path(resourcePath()) # add this line
    my_app = MyApp()

Resources_add_path()は、データ/.kvファイルを探す場所をKivyに指示します。たとえば、Macではpyinstallerアプリを実行すると、/ private/var/folder/80/y766cxq10fb_794019j7qgnh0000gn/T/_MEI25602を指し、Windowsではc:\ users\raj\AppData\Local\Temp_MEI64zTut(これらのフォルダーはアプリの終了後に削除され、再度起動すると別の名前が作成されます)。

次のコマンドを使用して、最初のMacテンプレートスペックファイルを作成しました。

pyinstaller --onefile -y --clean --windowed --name myapp --icon = ../../ Code/Data/myapp.icns --exclude-module _tkinter --exclude-module Tkinter --exclude-moduleエンチャント--exclude-moduletwisted ../../ Code/MyApp.py

変更されたMacOSスペックファイルは次のとおりです。

# -*- mode: python -*-

block_cipher = None


a = Analysis(['../../Code/MyApp.py'],
            pathex=['/Users/raj/Development/Build/mac', 
            '../../MyHiddenImports'],    
            binaries=None,
            datas=None,
            hiddenimports=['MyHiddenImports'],    
            hookspath=[],
            runtime_hooks=[],
            excludes=['_tkinter', 'Tkinter', 'enchant', 'twisted'],
            win_no_prefer_redirects=False,
            win_private_assemblies=False,
            cipher=block_cipher)

pyz = PYZ(a.pure, a.zipped_data,
            cipher=block_cipher)

a.datas += [('myapp.kv', '../../MyCode/my.kv', 'DATA')]

exe = EXE(pyz, Tree('../../Code/Data', 'Data'), 
            a.scripts,
            a.binaries,
            a.zipfiles,
            a.datas,
            name='myapp',
            debug=False,
            strip=False,
            upx=True,
            console=False , icon='../../Code/Data/myapp.icns')

app = BUNDLE(exe,
             name='myapp.app',
             icon='../../Code/Data/myapp.icns',
             bundle_identifier=None)

注意事項:隠しインポートパスをpathexに追加し、hiddenimportsでパッケージを参照しました。 myapp.kvファイルをa.datasに追加して、アプリにコピーされるようにしました。 EXEで、データツリーを追加しました。 Dataフォルダーをアプリにコピーしたかったので(子をルートレベルに配置するのではなく)、プレフィックス引数を含めました。

コードをコンパイルしてアプリを作成し、それをdmgファイルに入れるために、次のことを行うmake-myappスクリプトがあります。

 pyinstaller -y --clean --windowed myapp.spec 
 pushd dist 
 hdiutil create ./myapp.dmg -srcfolder myapp.app -ov 
 popd 
 cp./dist/myapp.dmg。

同様に、Windowsのスペックファイルは次のとおりです。

# -*- mode: python -*-

from kivy.deps import sdl2, glew

block_cipher = None


a = Analysis(['..\\..\\Code\\Cobbler.py'],
             pathex=['E:\\Development\\MyApp\\Build\\pc',
             '..\\..\\MyHiddenImports'],
             binaries=None,
             datas=None,
             hiddenimports=['MyHiddenImports'],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)

pyz = PYZ(a.pure, a.zipped_data,
         cipher=block_cipher)

a.datas += [('myapp.kv', '../../Code/myapp.kv', 'DATA')]

exe = EXE(pyz, Tree('..\\..\\Code\\Data','Data'),
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
          name='myapp',
          debug=False,
          strip=False,
          upx=True,
          console=False, icon='..\\..\\Code\\Data\\myapp.ico' )

そして、Windowsアプリをコンパイルするには:

python -m PyInstaller myapp.spec

6
Raj

コードの長さを気にしない場合は、Builder.load_stringを使用して.pyファイル内にkvデータをロードするのはどうですか?このようにして、コード全体がpythonスクリプト内に保持され、.exeにコンパイルするのに役立つ場合があります。

1
illright