How to embed qml-files etc. in executable file? [solved]
-
wrote on 3 May 2011, 21:03 last edited by
I created a desktop-application (for MacOS and Windows) using QML.
Now I've got a lot of qml-files (hence using the QML Desktop components mentioned here http://labs.qt.nokia.com/2011/03/10/qml-components-for-desktop/).I'd like to embed them in the executable so the user can't tinker with them.
How do I do that?
-
wrote on 3 May 2011, 21:25 last edited by
Create a resource file (*.qrc) in your project and add your qml files to that. You can add the qrc file through creator and also use it to add files. After re-running qmake, the build process will process your qrc file with the rcc tool which will compile your files into an object file ready for linking into your application.
In your application you should refer to your qml files using the ":/path/to/my/qml/file.qml" syntax so that QFile knows you are referring to a compiled in resource.
-
wrote on 3 May 2011, 21:29 last edited by
I've got one more problem with this:
It can't find the file included in my resource-file.That's the content of my resource.qrc
@<RCC>
<qresource>
<file>qml/MyProject/main.qml</file>
</qresource>
</RCC>
@I added this to the .pro-file:
@# Compile Resources in Binary
RESOURCES +=
resources.qrc@Then I ran qmake and tried this in my main.cpp:
@viewer.setMainQmlFile(QString(":/qml/MyProject/main.qml"));@
The application returns the following error:
@file:///D:/MyProject/:/qml/MyProject/main.qml: File not found @
What am I doing wrong?
-
wrote on 3 May 2011, 23:53 last edited by
I'm not sure, but it may be that setMainQmlFile() is looking for a URL (directly or eventually), and thus needs a qrc scheme (rather than a :/ prefix).
For reference, the official docs on using QML and resource files together can be found at http://doc.qt.nokia.com/4.7-snapshot/qtbinding.html#managing-resource-files-with-the-qt-resource-system
Regards,
Michael -
wrote on 4 May 2011, 07:43 last edited by
In one of my current projects I have:
@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
</RCC>
@Then I set the source on the declarative view with:
@
view->setSource( QUrl( "qrc:/main.qml" ) );
@Try wrapping your path in a QUrl and using the qrc:/ scheme rather than the shorthand :/ that I suggested before.
-
wrote on 4 May 2011, 07:52 last edited by
Thanks ZapB, that did the trick.
Now I'm facing another problem though.In my main.qml I include the qml desktop-components like this:
@import "../../desktop-components/components"
import "../../desktop-components/components/plugin"@When the main.qml-file is compiled as a resource these paths don't match anymore.
How can I fix this?
-
wrote on 4 May 2011, 08:04 last edited by
The problem is that your main qml file is no longer located on the local filesystem, it is part of the virtual qrc:/ filesystem. The docs state that the default locations searched by the declarative engine when trying to import extra qml modules are:
- The directory of the current file (qrc:/ in this case)
- The locations specified by QLibraryInfo::ImportsPath
- Paths specified by the QML_IMPORT_PATH environment variable.
You can add extra directories to be searched by either:
- calling "QDeclarativeEngine::addImportPath()":http://doc.qt.nokia.com/latest/qdeclarativeengine.html#addImportPath or
- adding paths to the QML_IMPORT_PATH environment variable
I would recommend using the "QDeclarativeEngine::addImportPath()":http://doc.qt.nokia.com/latest/qdeclarativeengine.html#addImportPath option if you wish to force a certain deployment layout for your files.
-
wrote on 4 May 2011, 08:33 last edited by
Thanks for clarifying this.
I'd love to put all stuff of both import-folders in resource-files, but there is no way to add whole folders to a qrc-file or is there?
-
wrote on 4 May 2011, 08:39 last edited by
Sure. Open up the resource file in creator, click the Add->Files... button. In the resulting file dialog navigate to one of the dirs you wish to add. Select all the files in there and click OK. Repeat for the other dir of files.
My full resource file for the project I was talking about looks like this:
@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>Profile.qml</file>
<file>LineEdit.qml</file>
<file>Login.qml</file>
<file>images/clear.png</file>
<file>images/lineedit-bg-focus.png</file>
<file>images/lineedit-bg.png</file>
<file>images/qt-logo.png</file>
<file>images/qtdn-logo.png</file>
<file>images/login-button.png</file>
<file>SimpleButton.qml</file>
<file>images/login-button-shadow.png</file>
<file>images/application-exit.png</file>
<file>RemoteImage.qml</file>
<file>Photo.qml</file>
<file>images/box-shadow.png</file>
<file>SimpleProgressBar.qml</file>
<file>ProgressSpinner.qml</file>
</qresource>
</RCC>
@
Note that I have images as well as qml files in there. -
wrote on 4 May 2011, 08:55 last edited by
Yes I think that should work once you add the components to your resource file.
-
wrote on 4 May 2011, 20:05 last edited by
Hmm it seems to work but I'm running into a problem.
The compiler says:
@qrc:/qml/MyProject/main.qml:2:1: module ":.desktop-components.components" plugin "styleplugin" not found @This is qrc-file:
@<RCC>
<qresource prefix="/">
<file>qml/MyProject/main.qml</file>
<file>desktop-components/components/Button.qml</file>
<file>desktop-components/components/ButtonRow.qml</file>
<file>desktop-components/components/CheckBox.qml</file>
<file>desktop-components/components/ChoiceList.qml</file>
<file>desktop-components/components/components.pro</file>
<file>desktop-components/components/ContextMenu.qml</file>
<file>desktop-components/components/Dial.qml</file>
<file>desktop-components/components/Frame.qml</file>
<file>desktop-components/components/GroupBox.qml</file>
<file>desktop-components/components/HeaderSection.qml</file>
<file>desktop-components/components/Makefile</file>
<file>desktop-components/components/ProgressBar.qml</file>
<file>desktop-components/components/qmldir</file>
<file>desktop-components/components/RadioButton.qml</file>
<file>desktop-components/components/ScrollArea.qml</file>
<file>desktop-components/components/ScrollBar.qml</file>
<file>desktop-components/components/Slider.qml</file>
<file>desktop-components/components/SpinBox.qml</file>
<file>desktop-components/components/Switch.qml</file>
<file>desktop-components/components/Tab.qml</file>
<file>desktop-components/components/TabBar.qml</file>
<file>desktop-components/components/TabFrame.qml</file>
<file>desktop-components/components/TableView.qml</file>
<file>desktop-components/components/TextArea.qml</file>
<file>desktop-components/components/TextField.qml</file>
<file>desktop-components/components/ToolBar.qml</file>
<file>desktop-components/components/ToolButton.qml</file>
<file>desktop-components/components/plugin/libstyleplugin.a</file>
<file>desktop-components/components/plugin/styleplugin.dll</file>
</qresource>
</RCC>
@This is the start of main.qml
@import QtQuick 1.0
import "qrc:/desktop-components/components"
import "qrc:/desktop-components/components/plugin"@ -
wrote on 4 May 2011, 20:39 last edited by
Ah, you cannot compile a dll into the resource system. I do not think the library loader supports using the resource system. Also it doesn't really make sense to place a shared library inside the binary as it loses any benefit of being a shared library.
I think you'll need to remove your style plugin from the resource system and load that using the method I suggested above with QDeclarativeEngine::addImportPath().
-
wrote on 4 May 2011, 20:55 last edited by
Ah! I almost forget that libraries can't be resources.
It works now when styleplugin.dll is inside the .exe-folder.
I also placed a copy of styleplugin.dll inside the folder 'plugins' and added the following line in my main-function
@QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + "/plugins");@
but that doesn't work. What could be wrong here? applicationDirPath() returns the correct location.
-
wrote on 4 May 2011, 21:03 last edited by
What category of plugin is it?
-
wrote on 4 May 2011, 21:06 last edited by
It's a qml-plugin.
-
wrote on 4 May 2011, 21:11 last edited by
In that case I think that you need to use QDeclarativeEngine::addImportPath() as I mentioed earlier rather than addLibraryPath().
-
wrote on 4 May 2011, 21:24 last edited by
OK, but that returns an error (I placed it in the main-function)
@QDeclarativeEngine::addImportPath(QCoreApplication::applicationDirPath() + "/plugins");@
@error: incomplete type 'QDeclarativeEngine' used in nested name specifier@
Adding it to the QmlApplicationViewer doesn't do anything
@ QmlApplicationViewer viewer;
viewer.addImportPath(QCoreApplication::applicationDirPath() + "/plugins");@Also the QtCreator-editor complains that it can't find both imports:
@import "qrc:/desktop-components/components"
import "qrc:/desktop-components/components/plugin"@ -
wrote on 30 Dec 2012, 16:08 last edited by
You set it solved but i can't see solution.. Could you write me solution?
-
wrote on 10 Jan 2013, 16:36 last edited by
I think we can't load library in such way. For me problem solution was in modifying qstyleplugin and build rules. If needed I can share the code.