首页 > 解决方案 > 在 KDE Linux 上部署 QtQuick QML Python 项目

问题描述

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

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

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

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

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

QCoreApplication.applicationDirPath()

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

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

这是我的 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_())

这是我的观点.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'))

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

这个问题与特定于分发的包装无关。假设我将使用类似于此处讨论的“通用”方法——例如 shell 脚本(并假设安装用户将拥有 sudo 权限)。

标签: pythonqmlpyqt5kde

解决方案


这种情况下的想法是使用相对于主元素的相对路径创建绝对路径。例如,在这种情况下,您可以使用 main.py 目录路径(可以通过为此答案提供的解决方案获得:如何获取当前正在执行的文件的路径和名称?)来获取其他路径。

import os
import sys

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


CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))


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

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

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

推荐阅读