在 KDE Linux 上部署 QtQuick QML Python 项目

Deploy a QtQuick QML Python project on KDE Linux

我需要有关如何在 KDE 上的简单 QtQuick QML Python 应用程序中指定 QML 和资源(图标)路径的建议。我在这里发现的唯一相关问题是:Deploy a Qt project on linux

我的问题不一样。我部署应用程序的唯一目标是 KDE;因此,我不需要捆绑 Qt 库,我的应用程序也没有其他依赖项。我只需要部署我的 python 和 QML 文件以及一个应用程序图标 (png)。

另一个问题是,将来我希望能够仅通过 QML 文件提供某些更新。我计划在需要时推出一个新的 QML 文件,而无需部署新版本的应用程序。

这让我相信我应该使用Qt资源系统。但是,由于缺乏使用该系统或一般部署应用程序的经验,我寻求建议。

我不想在部署时在我的 main.py 文件中对我的图标和主 QML 文件 的路径进行硬编码。此外,以下代码没有提供任何应用程序文件的位置:

QCoreApplication.applicationDirPath()

它returns /usr/bin(python的位置)不是适合我的QML文件或应用程序图标的位置。

如何在执行 __main__ 方法中找到我的 QML 和资源文件?

这是我的 main.py:

import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QUrl
from PyQt5.QtQml import QQmlApplicationEngine
from PyQt5.QtGui import QIcon


if __name__ == '__main__':
    app = QApplication(sys.argv)

    engine = QQmlApplicationEngine()
    engine.load(QUrl.fromLocalFile('view.qml'))
    app.setWindowIcon(QIcon('appicon.png'))

    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec_())

这是我的 view.qml

import QtQuick.Window 2.2
import QtQuick 2.2
import QtQuick.Controls 2.14

Window {
    id: root
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    }

当我从本地目录执行 python main.py 时,此代码有效。但是,如果我将 python、qml 和图标文件部署到 /usr/local/bin,我必须将该路径硬编码到 python 文件中,如下所示。

    engine.load(QUrl.fromLocalFile('/usr/local/bin/view.qml'))
    app.setWindowIcon(QIcon('/usr/local/bin/appicon.png'))

我不想这样做。我正在寻找不涉及对路径进行硬编码的其他替代方案。

此问题与特定于发行版的包装无关。假设我将使用类似于 here 中讨论的 "generic" 方法的方法——例如 shell 脚本(并假设安装用户将拥有 sudo 权限)。

本例中的想法是使用相对于主要元素的相对路径创建绝对路径。例如,在这种情况下,您可以使用 main.py 目录路径(可以通过此答案提供的解决方案获得:How do I get the path and name of the file that is currently executing?)来获取其他路径。

<b>import os</b>
import sys

from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQml import QQmlApplicationEngine


<b>CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))</b>


if __name__ == "__main__":
    app = QApplication(sys.argv)

    engine = QQmlApplicationEngine()
    engine.load(QUrl.fromLocalFile(<b>os.path.join(CURRENT_DIR, "view.qml")</b>))
    app.setWindowIcon(QIcon(<b>os.path.join(CURRENT_DIR, "appicon.png")</b>))

    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec_())
├── appicon.png
├── main.py
└── view.qml