【问题标题】:QML: how to specify image file path relative to application folderQML:如何指定相对于应用程序文件夹的图像文件路径
【发布时间】:2015-02-17 10:11:59
【问题描述】:

我们正在开发我们的第一个 Qt/QML 应用程序(尝试技术)。乍看之下,技术看起来很有前途,但我们遇到了很多意想不到的奇怪问题,几乎在一开始就放弃了。

这里有一个这样的问题。

我们希望我们的应用程序具有以下文件夹布局:

--> ApplicationFolder
|--> qml        // QML files (also structured by subfolders)
|--> resources  // Application resources (images, sounds, data-files, etc.)
| |--> images   // Image resources (also structured by subfolders)
| |--> data     // Different data files
| |--> ...      // Other resources
|--> Application.exe   // Application executable
|--> *.dll             // DLLs application depends on

问题是为了为Image QML 项目指定图像文件,我们必须使用相对于 QML 文件的路径?!这绝对是疯了。在开发过程中,文件有时会在文件夹之间移动(您移动 QML 文件并且必须修复它的所有路径?!);一些不同的 QML 文件必须引用相同的图像(相同的图像资源但不同 QML 文件中的实际路径不同)。

所以问题是:如何指定相对于应用程序文件夹的图像路径?有可能吗?

提前致谢!

PS。在我们的例子中,使用 Qt 的资源系统(当资源嵌入到可执行文件中时)不是一个选项。我们需要磁盘上的原始资源(包括 QML 文件本身,至少在开发阶段)。

PPS。花了一整天时间通过文档/google/stackoverflow自己解决问题后写了这个问题;根本没有成功(大多数示例使用资源嵌入,其他示例过于简单,仅使用相对路径)。

【问题讨论】:

  • This is absolutely insane. During development files sometimes moved between folders (you move QML file and have to fix all the path it has ?!); -> 在开发阶段开发有什么疯狂之处?显然,如果你没有正确设计它,只是进行货物狂热的编程,你可能需要用新的设计重新实现一些东西。当你重命名某个东西时,因为你意识到你给一个变量起错误的名字,你在任何地方都重命名它是不是也很疯狂?来吧,Alexey... :) Sed 是你的朋友...
  • @lpapp 这太疯狂了,因为如果图像文件保持在同一个地方,那么绝对通常希望在应用程序代码中对该文件的引用保持不变并且不依赖于移动其他东西。不是吗?如果某个 QML 文件引用了某个图像,而该图像始终位于同一个位置,为什么每次要将 QML 移动到其他文件夹时都需要修复该 QML?这就是我所说的。使用 qrc 文件时,您没有这样的问题,但不幸的是,我们无法找到原始资源的解决方案。

标签: qt qml qtquick2


【解决方案1】:

如果您的图片无法使用 .qrc 文件,您可以试试这个:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("applicationDirPath", QGuiApplication::applicationDirPath());
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

在 QML 中,你会这样做:

Image {
    source: "file:///" + applicationDirPath + "/../resources/images/image.png"
}

请注意,此代码未经测试。

【讨论】:

  • 谢谢@Mitch!这似乎是一个可能的解决方案。刚刚测试过了。为了让它正常运行,需要在"file:///" 前面加上QGuiApplication::applicationDirPath()。而且似乎注入的applicationDirPath 值在应用程序加载的所有QML 文件中都可用,而不仅仅是在engine.load(...) 加载的主文件中(我一开始就担心它)。可以通过传递进程的当前工作目录进行一些改进,以避免在相对资源路径中出现/../,并且应该在 QT Creator 中的调试运行和独立应用程序运行中工作。非常感谢!
  • 我不能说,因为我没有用基准测试过。不过,使用 Qt Creator 的项目向导设置基准非常容易(甚至是 QML 基准),Creator 的 QML Profiler 可以帮助您查明任何瓶颈。
  • 谢谢@Mitch!将调查 QML 分析。
  • 只需要把file:///放在前面。感谢您发表评论@AlexeyKryshen!
  • 这对我不起作用,Android设备也一样吗?
【解决方案2】:
Image {
   source: "file:resources/images/image.png"
}

将工作如果工作目录设置为ApplicationFolder

注意:从 QtCreator 运行时,请仔细检查应用程序实际运行的目录(我的应用程序在我的主目录中运行,即使在运行配置中正确设置了工作目录(在终端中运行一次之后)窗口神奇地自行修复))

【讨论】:

  • 我建议不要这样做并使用 QStandardpaths 或类似的东西,因为这在 cwd 不是 appdir 的环境中不起作用。
【解决方案3】:

老问题,但从谷歌得到这里。对我来说,它只适用于这样的相对路径:

import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.3

[...]    

Image {
    id: image
    source: "icons/brightness.svg" // simple relative path
    width: 22
    height: 22
    sourceSize.width: 22 // svg render resolution
    sourceSize.height: 22
    fillMode: Image.PreserveAspectFit // just in case to avoid stretching
}

不需要 .qrc。

【讨论】:

    猜你喜欢
    • 2012-04-28
    • 2011-03-15
    • 2013-12-20
    • 2014-08-23
    • 1970-01-01
    • 2018-01-27
    • 2019-03-31
    • 2013-04-16
    • 1970-01-01
    相关资源
    最近更新 更多