【问题标题】:PyInstaller and QML FilesPyInstaller 和 QML 文件
【发布时间】:2021-08-18 06:25:48
【问题描述】:

如何将 QML 文件作为单个可执行文件包含到我的 Python 项目中。当我运行pyinstaller --onefile main.py 时,运行可执行文件会导致找不到QML 文件的错误。除非我使用绝对路径或将 view.qml 放在与我的可执行文件相同的目录中。我不想有一个单独的 QML 文件,我希望它合并到可执行文件中。

main.py:

if __name__ == "__main__":
  app = QGuiApplication(sys.argv)
  engine = QQmlApplicationEngine()
  engine.load(QUrl("view.qml"))
  sys.exit(app.exec_())

view.qml:

import QtQuick 2.0

ApplicationWindow {
  id: window
  title: "Window"
  width: 900
  height: 600
  visible: true
}

【问题讨论】:

标签: python qml pyinstaller pyside2


【解决方案1】:

我的答案除了展示如何在这种特殊情况下使用可能的重复答案外,还展示了使用 Qt 自己的工具的替代方法。

1.将 .qml 复制到同一个可执行文件夹

在这种情况下,您必须使用应用程序路径构建 qml 的绝对路径。

import os
import sys

from PySide2 import QtCore, QtGui, QtQml

# https://stackoverflow.com/a/404750/6622587
application_path = (
    os.path.dirname(sys.executable)
    if getattr(sys, "frozen", False)
    else os.path.dirname(os.path.abspath(__file__))
)


if __name__ == "__main__":
    import os
    import sys

    app = QtGui.QGuiApplication(sys.argv)
    engine = QtQml.QQmlApplicationEngine()
    file = os.path.join(application_path, "main.qml")
    engine.load(QtCore.QUrl.fromLocalFile(file))
    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec_())

然后将 .qml 复制到同一个可执行文件夹中。

2。将 .qml 添加为 data files

数据文件解压到sys._MEIPASS相对文件夹中,如果不使用--onefile选项则该路径为可执行文件夹,否则解压到临时文件夹中。

在您的情况下,它实现了以下功能:

├── main.py
└── main.qml

ma​​in.py

import os
import sys

from PySide2 import QtCore, QtGui, QtQml

# https://stackoverflow.com/a/42615559/6622587
application_path = (
    sys._MEIPASS
    if getattr(sys, "frozen", False)
    else os.path.dirname(os.path.abspath(__file__))
)


if __name__ == "__main__":
    import os
    import sys

    app = QtGui.QGuiApplication(sys.argv)
    engine = QtQml.QQmlApplicationEngine()
    file = os.path.join(application_path, "main.qml")
    engine.load(QtCore.QUrl.fromLocalFile(file))
    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec_())

并按如下方式运行pyinstaller:

pyinstaller --add-data "main.qml:." --onefile main.py

3.使用Qt Resource

您可以创建一个添加 qml 的 .qrc,然后将它们转换为 .py,最后将其包含在 .py 中。

├── main.py
├── main.qml
└── qml.qrc

ma​​in.py

import sys

from PySide2 import QtCore, QtGui, QtQml

import qml_rc


if __name__ == "__main__":
    import os
    import sys

    app = QtGui.QGuiApplication(sys.argv)
    engine = QtQml.QQmlApplicationEngine()
    engine.load(":/main.qml")
    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec_())

qml.qrc

<RCC>
  <qresource prefix="/">
    <file>main.qml</file>
  </qresource>
</RCC>

要将 qml.qrc 转换为 .py,您必须使用以下命令:

pyside2-rcc qml.qrc -o qml_rc.py 

最后因为它已经是一个 .py 我们只运行 pyinstaller:

pyinstaller main.py --onefile

【讨论】:

  • 太棒了!非常有用的解释。你帮助我理解了很多。我已经在您的答案中尝试了第二种方法,并且效果很好。能够只维护 .spec 文件以包含我所有额外的“DATA”文件,这真是太好了。谢谢
猜你喜欢
  • 2012-09-13
  • 2016-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-15
  • 2021-09-09
  • 2020-08-16
相关资源
最近更新 更多