web-dev-qa-db-ja.com

PyInstaller + UIファイル-FileNotFoundError:[Errno 2]そのようなファイルまたはディレクトリはありません:

QtDesignerを使用して作成された.uiファイルに依存するPyInstallerを使用して.pyスクリプトを.exeにエクスポートしようとしています。

PyCharmを介して実行すると、.pyスクリプトが正常に機能することを確認できます-.uiファイルを使用して作成したGUIを確認できます。

ただし、.pyスクリプトを.exeにエクスポートして起動すると、コマンドラインで次のエラーが発生します。

C:\Users\giranm>"C:\Users\giranm\PycharmProjects\PyQt Tutorial\dist\secSearch_demo.exe"
Traceback (most recent call last):
  File "secSearch_demo.py", line 13, in <module>
  File "site-packages\PyQt4\uic\__init__.py", line 208, in loadUiType
  File "site-packages\PyQt4\uic\Compiler\compiler.py", line 140, in compileUi
  File "site-packages\PyQt4\uic\uiparser.py", line 974, in parse
  File "xml\etree\ElementTree.py", line 1186, in parse
  File "xml\etree\ElementTree.py", line 587, in parse
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\giranm\\securitySearchForm.ui'
Failed to execute script secSearch_demo

何らかの理由で、.exeファイルはパス内の.uiファイルを探しています-C:\ Users\giranm \

ただし、すでにいくつかの調査を行った後、os.getcwd()を使用して、スクリプトにフルパスがあることを確認する必要があると言われました。以下のコードを使用しても、.uiファイルを見つけようとするとエラーが発生します。

PyInstaller:IOError:[Errno 2]そのようなファイルまたはディレクトリはありません:

# import relevant modules etc...

cwd = os.getcwd()
securitySearchForm = os.path.join(cwd, "securitySearchForm.ui")
popboxForm = os.path.join(cwd, "popbox.ui")

Ui_MainWindow, QtBaseClass = uic.loadUiType(securitySearchForm)
Ui_PopBox, QtSubClass = uic.loadUiType(popboxForm)

# remainder of code below.  

.uiファイルを.pyに変換し、pyuic4を使用してメインルーチンにインポートできることを知っています。ただし、.uiファイルを複数回編集するため、変換を続けることはできません。

スタンドアロンの.exeを作成できるようにこれを修正する方法はありますか?

私はPyQT4とPyInstallerの使用にかなり慣れていません-どんな助けでも大歓迎です!

12
giran

週末中ずっと頭を悩ませてSOをさらに調べた後、UIファイルを使用してスタンドアロンの.exeを期待どおりにコンパイルすることができました。

まず、この答えを使って次の関数を定義しました

PyInstaller(-onefile)を使用したデータファイルのバンドル

# Define function to import external files when using PyInstaller.
def resource_path(relative_path):
    """ Get absolute path to resource, works for dev and for PyInstaller """
    try:
        # PyInstaller creates a temp folder and stores path in _MEIPASS
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")

    return os.path.join(base_path, relative_path)

次に、この関数と必要なクラスの変数を使用して.UIファイルをインポートしました。

# Import .ui forms for the GUI using function resource_path()
securitySearchForm = resource_path("securitySearchForm.ui")
popboxForm = resource_path("popbox.ui")

Ui_MainWindow, QtBaseClass = uic.loadUiType(securitySearchForm)
Ui_PopBox, QtSubClass = uic.loadUiType(popboxForm)

次に、Qt Designerを使用してリソースファイル(.qrc)を作成し、このリソースファイルを使用して画像/アイコンを埋め込む必要がありました。完了したら、pyrcc4を使用して.qrcファイルを.pyファイルに変換しました。これはメインスクリプトにインポートされます。

ターミナル

C:\Users\giranm\PycharmProjects\PyQt Tutorial>pyrcc4 -py3 resources.qrc -o resources_rc.py

Python

import resources_rc

メインの.pyスクリプトが機能することを確認したら、PyInstallerを使用して.specファイルを作成しました。

ターミナル

C:\Users\giranm\PycharmProjects\PyQt Tutorial>pyi-makespec --noconsole --onefile secSearch_demo.py

PyInstallerのガイドに従って、上記の.specファイルを変更してデータファイルを追加しました。

https://pythonhosted.org/PyInstaller/spec-files.html#adding-data-files

最後に、上記の.specファイルを使用して.exeをコンパイルしました。

11
giran

あなたは単に使うことができます:

uic.loadUi(r'E:\Development\Python\your_ui.ui', self)

フルパスを使用し、標準の引数でpyinstallerを使用すると、正常に機能します。 rprefix は、円記号が文字通りに解釈されることを確認します。

1
Martin Kasche