Switching between qrc and local path for qml files - qt

As far as i know, the qml files could be loaded from local directory path or could be bundled in qrc file and loaded with qrc:/ URI. In debugging phase changing local qml files doesn't need recompilation of qrc file and linking together with main executable, which is fast procedure for try and error fine tuning. But in deploy phase, the qml files should be bundled together as qrc file and link to main C++ Qt application. This is good practice when you want have single executable file, however compiling qrc file and linking it again is time consuming for big projects. is there any way we can switch to qrc or local directory? for example in debug and release mode?
There is many qml components inside the project and all of these are created by URI's like qrc:/componenentname.qml inside another qml files.
So is there any way to interchange these two states in debug and release modes, and keeping qml files without duplicate changes?

All URLs inside QML, if not specified in full, are relative to the current file.
E.g. if a QML file has content like this
Image {
source: "images/foo.png"
}
then the full URL of the image is constructed at runtime based on the base URL of the QML file itself.
I.e. if the QML file itself is qrc://main.qml then the resulting path is qrc://images/foo.png, if the QML file itself is file:///path/to/your/project/main.qml then the resulting image source is file:///path/to/your/project/image/foo.png.
So if you keep URLs relative in your usage inside QML, you can simply switch between resource and local files when loading the primary QML file.
QUrl mainFile = localMode ? QUrl::fromLocalFile("main.qml") : QUrl("qrc://main.qml")
QQuickView view;
view.setSource(mainFile);

Sorry for the old post,
What we did to handle this is use Qts resource search path. We used PySide2 so examples are in python
try:
QDir.addSearchPath('search_path_name', 'path/to/root/resources')
engine.load('search_path_name:/main.qml')
except FileNotFoundError:
try:
import qml # compiled resources using pyside resource compiler
QDir.addSearchPath('search_path_name', ':/')
engine.load('qrc:///main.qml')
except ModuleNotFoundError:
pass
From this point on resources are loaded using QFile("search_path_name:some_file.txt") and it will load from either search path.

Related

How do I split out QML files embedded within a DLL?

I have QML file that has been embedded into a dll. I think it was done something like this
How can I embed a Qt resource into a .dll file?
(The second answer).
Is there anyway to split out the QML file to obtain the source code? I am not very familiar with QT framework
If it's embedded via *.qrc, then it's NOT compatible with standard windows/linux (.dll/.so) resource formats. qrc is compiled as xxx_qrc.cpp file and embedded by linker as .obj file with static initialization code. I.e. it's just part of the binary. You can access "contents" of qrc via QFile with "qrc:/." URL. But for that, you have to load DLL with resources embedded in current process, because qrc is hooked up in static initialization (aka DllMain in Windows). Something like:
QLibrary lib("./library.dll");
if (!lib.load())
throw exception(lib.errorString().toStdString());
QFile resource(":/resource.qml");
if (!resource.open(QIODevice::ReadOnly))
throw exception(resource.errorString().toStdString());
resource.copy("./exported.qml");
To explore currently loaded virtual qrc file system tree, you can use QDir(":/"). I guess it's pretty easy to figure out the rest from here.
And of course - you have to be aware what sort of DLLs you are loading into your process, as they may contain arbitrary code that will be executed as you call QLibrary::load!

How do I access Qt qrc folder directly Qt 5.10.1

I am developing an application in qml.
I have a folder qrc folder structure like ,
qrc:
Features
- Media
- Audio
- TV
graphics
- media_assets
- audio_assets
- tv_assets
Features contains respective qml files and graphics contains the graphics.
My issue is, after loading a qml file from the features it set as the current directly then, after that when I try to access the graphics folder I need to go back ../.../ and access the folder. It is making problems when folder structure is changed.
How can I access the graphics directly from qrc like graphics/media_assets/ from any qml files
In the older versions I could access the graphics directly by using "file://sample.png", in qt 5.10.1 it is deprecated.
Use:
qrc:///
From url QML Basic Type documentation:
When referring to files stored with the Qt Resource System from within
QML, you should use "qrc:///" instead of ":/" as QML requires URL
paths. Relative URLs resolved from within that file will use the same
protocol.

Deploy QML application with localstorage plugin

I have deployed a QML application (static build on windows, following this how-to: http://qt-project.org/wiki/How-to-build-a-static-Qt-for-Windows-MinGW). However, the qml_import_trace (screenshot below) reveals that LocalStorage is loaded from the Qt/Static folder on the development computer, not from the release folder. Hence, when launched at another computer, the LocalStorage module is not found. How may the LocalStorage plugin/module be shipped with the application?
Including the following lines in the .pro files will give svg support. Am I only missing a qtplugin for sql/localstorage? In that case, what is the proper plugin name? Also, where can I find valid inputs for QTPLUGIN+= and QT+= ?
QTPLUGIN += qsvg
QT += svg sql
If I understand you correctly you want to copy the needed files to the release folder automatically.
Use the windeployqt.exe (in qt/bin folder) with --qmldir option. It will scan the given path for QML files and collect the QML components imported in those files.
A solution, although not optimal, was to manually copy the QtQuick/LocalStorage folder from the static folder into the release folder

Get path of file in external library

I have 2 Qt projects that I've made. One builds a library the other builds a GUI that uses that library. My project with the library includes a bunch of shaders that I've made. Within my GUI I want to reference the path to these shaders. My approach is to have a static function in my library called getLibraryPath() that returns a QString referencing the path on my file system to the library.
I've tried using QDir::currentPath() and QApplication::applicationFilePath() and other similar functions that return paths but they all return paths referencing my GUI's path, not the library's path even though the function to get the path is located inside the library.
Within my GUI I try to reference a shader by doing: Shader->addShaderFromSourceFile(QGLShader::Vertex, MyExternalLib::getLibraryPath() + "/shaders/MyVertexShader.vs");
A library is just a bunch of code. It has no notion of having its own path. The normal way of doing what you intend to is:
If the library is a separately installed product -- set a registry entry in the installer, and check it at runtime. This will be platform specific, unless the library is written in Qt -- then you can use QSettings, but make sure that you set your company name, application, etc. appropriately as it's not done by QApplication for you anymore.
If the library is installed as a part of your application, in the same folder tree: use QCoreApplication::applicationDirPath() and add a relative path between the application executable and the files you want to this path.
I was able to solve this by adding the files I want to reference to a qrc file within my library project. By doing this, I could then reference the qrc path and the files inside of them easily.

Using Qt Creator in QML Design mode, how to reference an image using qrc path?

So, we have an embedded Linux system running Qt and we compile all of our icons (.png format) into our executable using the resource file. The problem is that I want to be able to use the Qt Creator QML Designer to visually see our screens as we are laying them out, but it only allows me to select a relative file system path (i.e. not a path to the resource). If I go to edit mode and put the qrc:/image.png it works in run time but the image doesn't show up in the QML Design mode. Has anyone ever done this or know if it is possible?
There is at least a workaround:
Put everything in the resource file (the qml files and the icons), and when you'll edit the file in Qt Quick Designer, all paths will be relative so the icons will be visible.
Everything is described there: Managing resource files with the Qt resource system
And to avoid deploying the qml files, you'll have to remove/comment the following line from your .pro:
DEPLOYMENTFOLDERS = folder_01
and replace it with:
OTHER_FILES = <list of qml files>

Resources