PyInstaller 和 QML 文件 [英] PyInstaller and QML Files

查看:66
本文介绍了PyInstaller 和 QML 文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How can I include the QML file into my Python project as a single executable. When I run pyinstaller --onefile main.py, running the executable results in an error that the QML file is not found. Unless I use an absolute path or place view.qml in the same directory as my executable. I don't want to have a separate QML file, I want it combined into the executable.

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
}

推荐答案

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

My answer in addition to showing how to use the possible duplicate answer in this particular case, also shows an alternative using Qt's own tools.

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

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

In this case you have to build the absolute path of the qml using the application path.

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 复制到同一个可执行文件夹中.

Then copy the .qml to the same executable folder.

2.将 .qml 添加到 数据文件

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

The data files are decompressed in the folder relative to sys._MEIPASS, if the --onefile option is not used then that path is the executable folder otherwise it will be decompressed in the temporary folder.

在您的情况下,它实现了以下内容:

In your case it implements the following:

├── 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如下:

And run pyinstaller as follows:

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

<小时>

3.使用 Qt 资源

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

You can create a .qrc that adds the qml, then convert them to .py and finally include it in the .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,您必须使用以下命令:

To convert the qml.qrc to .py you must use the following command:

pyside2-rcc qml.qrc -o qml_rc.py 

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

and finally as it is already a .py we only run pyinstaller:

pyinstaller main.py --onefile

这篇关于PyInstaller 和 QML 文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆