web-dev-qa-db-ja.com

pyside2アプリケーションのデプロイ方法は? -Qtの方法

pyside2アプリケーションをQt 5.12.1に基づいてすべての主要な3つのオペレーティングシステム( Windows、Linux、MacOS)。

私はすでにチェックしました Pythonスクリプトスタンドアロン実行可能ファイルを依存関係なしで実行する方法は? ですが、次のようなQt関連のアプローチが必要なので、それは私が望むものではありませんwindeployqtmacdeployqtlinuxdeployqt(個別のプロジェクト)。

Eyllanescが指摘したように: "pythonはバイナリを生成しないスクリプト言語です"。しかし、The Qt Companyもそれを理解し、pyside2アプリケーションを展開しやすくする必要があります。少なくともC++/QMLアプリケーションのデプロイと同じくらい簡単です。

windowsdeployqtmacdeployqtlinuxdeployqt...のようなツールが欲しいpyside2アプリケーションで動作します。

[UPDATE]eyllanesc推奨 fbs(fmanビルドシステム) デプロイする公式のツールがないため、開始点としてpyside2アプリケーション。これは回避策として機能するはずです。新しい答えも大歓迎です。
Qt Companyが公式ツールをリリースしたら、できるだけ早く回答してください。

[注意]:Qt Creator 4.8.1を使用していますQt 5.12.1

5
lateo96

必要なすべての依存関係をフォルダーにパックして配布します。

シンプルなアイデアですが、問題は最小限のセットを見つけることです。 qtサイトで提案されたパッケージャは、複雑なファイル構造と独自のEXEを作成しますが、これは小さなスクリプトの場合(IMHO)には多すぎます。幸い、依存関係をログに記録する方法があります。Windowsでは Process Monitor 、Linuxでは strace です。監視対象プログラムのすべてのシステムコールがリストされます。そのようなログから依存関係を選択するための小さなpythonスクリプトを記述しました。

ここに示すように、仮想環境でこれを実行すると便利です。または、python組み込みディストリビューションの必須モジュールがあらかじめインストールされています:

    > python -m venv ./MyVEnv
    > cd ./MyVEnv
    > ./.../python -m pip install pyside2
  1. syscallモニターを開始し(10秒のログでも巨大であるため、長時間実行しないでください)、Qtを使用してすべての依存関係をロードするスクリプトを開始します(すべての可能なアクションを実行して、必要なすべての依存関係を開きます)および閉じる(ロックされたもののロックを解除する); cpythonの-Bフラグを使用して、キャッシュされたファイルが最終パックに含まれないようにすることが役立つ場合があります。また、監視プログラムで不要なシステムコールを手動で除外して、ログを減らすこともできます

windowsの場合:

    > Procmon /AcceptEula /NoFilter /BackingFile log1
    > .\MyVEnv\...\python -B yourScript.py
    > Procmon.exe /OpenLog log1.PML /SaveAs logFile.csv

linuxの場合:

    > 2>logFile strace ./bin/python3 -B yourScript.py
  1. その後、スクリプトを起動して、ログに記録されたすべての依存関係をフォルダーに複製し、元のファイル構造を保持します。

    > python .\depspicker.py
    

それは:

    #depspicker.py
    #changes from Windows to Linux version commented

    logF = r".\logFile.CSV" #Linux: ./logFile
    basePath = r".\...\site-packages" #base of the file-tree to be copied (where the needed dependencies originally reside)
    destPath = r".\site-packages" #destination of copy


    import csv, shutil
    from pathlib import Path

    logF = Path(logFile)
    basePath = Path(basePath).resolve()
    destPath = Path(destPath).resolve()

    with open(logF, newline='', encoding="utf-8") as log:
        checked = set()
        reader = csv.DictReader(log) # Linux: -
         for row in reader: #Linux: for row in log:
            try:
                src = Path(row["Path"]) # Linux: src = Path(row.split('"')[1])
                src = src.resolve()
                if src in checked or not (src.is_file() and\
                    basePath.parts == src.parts[:len(basePath.parts)]):
                    continue
            except (OSError, IndexError): #not a file
                continue
            finally:
                checked.add(src)
            dst = destPath / src.relative_to(basePath)
            dst.parent.mkdir(parents=True, exist_ok=True)
            shutil.copy2(src, dst.parent)
  1. これで、「basePath」内のすべてを「destPath」から空きスペースまでの複製されたファイルツリーに置き換えることができます。プログラムを配布するには、python embeddedを取り、そこに新しい依存関係を置き、さらに同様に不要なファイルをすべて削除します。または最初からvenvの代わりにembeddedを使用します。
1
alexey