PDA

View Full Version : QQmlEngine::addImportPath(...) vs QML2_IMPORT_PATH difference?



viktoria.nemkin
14th April 2016, 13:22
I'm trying to install a qml module that I have created into my project.

Try 1: When I register it like this:


QQmlApplicationEngine engine;
engine.addImportPath("<path>");
engine.load(...);

in my main.cpp it builds and runs.

Try 2: When I add the same path like this:


QML_IMPORT_PATH += <path>
QML2_IMPORT_PATH += <path>


to my .pro file, it builds and then I get an error:

QQmlApplicationEngine failed to load component
qrc:/main.qml:4 module "mymodule" is not installed

Here is a minimal example:

C:/Users/vnemkin/Documents/example/example.pro


TEMPLATE = app

QT += qml quick widgets

CONFIG += c++11

SOURCES += main.cpp

RESOURCES += qml.qrc

# Additional import path used to resolve QML modules in Qt Creator's code model
# Try 2 : Uncomment these two, and it does not work.
#QML_IMPORT_PATH += C:/Users/vnemkin/Documents/
#QML2_IMPORT_PATH += C:/Users/vnemkin/Documents/

# Default rules for deployment.
include(deployment.pri)



C:/Users/vnemkin/Documents/example/main.cpp


#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtDebug>

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

QQmlApplicationEngine engine;
//Try 1 : Uncomment this, it works.
//engine.addImportPath("C:/Users/vnemkin/Documents");

for(QString path : engine.importPathList())
{
qDebug(path.toStdString().c_str());
}

engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

return app.exec();
}



C:/Users/vnemkin/Documents/example/main.qml


import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Dialogs 1.2
import mymodule 1.0

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


C:/Users/vnemkin/Documents/mymodule/qmldir


module mymodule

Example 1.0 Example.qml

C:/Users/vnemkin/Documents/mymodule/Example.qml


import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Dialogs 1.2

Button {

}


To me the Qt Documentation here seems to say both ways mentioned do the same thing:

"Additional import paths can be added through QQmlEngine::addImportPath() or the QML2_IMPORT_PATH environment variable."

http://doc.qt.io/qt-5/qtqml-syntax-imports.html

In my main.cpp I write to the debug console what engine.importPathList() contains. When I do Try 1, it contains the path, when I do Try 2, it does not.

The reason why I want to include my module in the .pro file is because there I have the $$PWD variable, and I can use that to specify the relative path from the .pro file to the module. In the .cpp code the only thing I know is where the exe is located, which depends on where we build our project.

Why is QML2_IMPORT_PATH not working for me?

I'm using:
QtCreator 3.6.1
Qt 5.6.0 (MSVC 2013, 32 bit)

Edit:

In project settings, if I go to "Run" and there "Run Environment", I have Use Build Environment specified, but it does not contain my variable.

If I add the variable:

QML2_IMPORT_PATH = C:/Users/vnemkin/Documents/

it builds and runs.

So essentially my question is: why does the build environment not contain the variables specified in my .pro file?

anda_skoa
14th April 2016, 13:53
To me the Qt Documentation here seems to say both ways mentioned do the same thing:

"Additional import paths can be added through QQmlEngine::addImportPath() or the QML2_IMPORT_PATH environment variable."

Did you set that environment variable somewhere?



The reason why I want to include my module in the .pro file is because there I have the $$PWD variable, and I can use that to specify the relative path from the .pro file to the module. In the .cpp code the only thing I know is where the exe is located, which depends on where we build our project.

Isn't the module built in a relative path?
Where to you plan to have it when the application is deployed/installed?



Why is QML2_IMPORT_PATH not working for me?

Have you actually set it in the environment you are launching the application from?



In project settings, if I go to "Run" and there "Run Environment", I have Use Build Environment specified, but it does not contain my variable.

If I add the variable:

QML2_IMPORT_PATH = C:/Users/vnemkin/Documents/

it builds and runs.

As it should.

So I take it you hadn't had set the variable before.




So essentially my question is: why does the build environment not contain the variables specified in my .pro file?
Not sure what you mean.

Your code snippets suggest that you have a qmake variable with the same name in your .pro file, do you have the actual environment variable set in the environment the build runs in?
I.e. did you run QtCreator in an environment with the variable set?

Cheers,
_

viktoria.nemkin
14th April 2016, 15:12
I did not run Qt with this environment variable set. So now I understand that the variables in the .pro file are not the same as build/run environment variables.

I want to have all the qmls inside the module to be built into the application/not deploy them separately. After reading your answer I think I should not be using a module for this. (?)

My original problem that made me start to use modules was that I have many projects in a folder, just like the example project I included in my question and I have a folder next to them just like mymodule which contains qmls used by all projects (common qml components I made).

However, when I try to include this folder in example/main.qml, like this:



import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Dialogs 1.2
//import mymodule 1.0
import "../mymodule"

ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")

Example{

}

}


In the code snippet Example is purple, which means the editor can find it in mymodule. But when I build it, it says "../mymodule" is not a directory.

If I copy paste the mymodule folder inside the project folder (to example/mymodule) and import "mymodule" it finds it and runs.

Also if I put import ".." it says ".." is not a directory.

Why can't I import anything above the project's folder?

anda_skoa
14th April 2016, 16:22
I did not run Qt with this environment variable set. So now I understand that the variables in the .pro file are not the same as build/run environment variables.

Right.



I want to have all the qmls inside the module to be built into the application/not deploy them separately. After reading your answer I think I should not be using a module for this. (?)

You could set the path during development to the local path you know and when you're done you add your module's files to a Qt resource and set the import path to include the resource path.

Or you just use the "relative path" syntax for import, which will get the QML files from the resource if the main QML file came from the resource or from the file system, if the main file was loaded from a local file.



In the code snippet Example is purple, which means the editor can find it in mymodule. But when I build it, it says "../mymodule" is not a directory.

That is a relative path "one directory up, then subdirectory mymodule", applied to the path of the current QML file.
So if your main.qml is example/main.qml, then "mymodule" and "example" need to be sibling directories.



Why can't I import anything above the project's folder?
I don't think there is any such restriction, check if you have the right relative path.

Cheers,
_

viktoria.nemkin
15th April 2016, 10:02
That is a relative path "one directory up, then subdirectory mymodule", applied to the path of the current QML file.
So if your main.qml is example/main.qml, then "mymodule" and "example" need to be sibling directories.


But they are. If you look at the example I included you can see the hierarchy (above all code snippets I put the absolute path to the file).

The only thing I modify in it is example/main.qml, where I remove the line

import mymodule 1.0

and add

import "../mymodule"

So I'm trying to import it as a simple directory, not a qmldir now.

Then I build it like this I get an error message saying qrc:/main.qml:4 "../mymodule": no such directory. But it is there.

anda_skoa
15th April 2016, 10:15
But they are. If you look at the example I included you can see the hierarchy (above all code snippets I put the absolute path to the file).

Yes, but you are not loading the files from disk.



Then I build it like this I get an error message saying qrc:/main.qml:4 "../mymodule": no such directory. But it is there.
You are loading main.qml from the resource system.
Try to apply "../mymodule" to that path and you end up with an invalid URL "qrc:/../mymodule"

Cheers,
_

viktoria.nemkin
15th April 2016, 10:44
Thank you! Now I understand it.