qmlRegisterType => QML module not found. How to specify the path to the object ?
-
wrote on 10 May 2019, 13:56 last edited by Quentin91 5 Oct 2019, 14:02
hi everyone !
I am trying to set a simple c++/QMl connection. I use qmlRegisterType<_>("a.b",1,0,"c"); and import a.b 1.0 in QML. But I can't find the right way to specify the path to my objectb c...
here is the QML code
import QtQuick 2.5 import QtQuick.Window 2.5 import QtQuick.controls 2.5 import miniModel.miniModel 1.0//QML module not found (minimodel.miniModel) ApplicationWindow { id: root width: 300 height: 480 visible: true property bool value: Minimodelqml.getMiniBoule BackEnd { id: backend } TextField { text: backend.userName placeholderText: qsTr("User name") anchors.centerIn: parent onTextChanged: backend.userName = text } }
I will use a lot of folders soon so I need to put my QML files together, headers together, QML source files together in a tools directory etc. so I have to specify a lot of paths everywhere and can't just put my files together so it works easily.
Here is my testFunction in main.cpp
#include "miniModel.h" bool testMiniModel(int ai_argc = 0, char** aipp_argv = nullptr) { printf("======================================================================\n=\t\t\tTEST MINIMODEL \t\t\t =\n======================================================================\n\n"); QGuiApplication app(ai_argc, aipp_argv); qmlRegisterType<MiniModel>("Inc.miniModel", 1, 0, "MiniModel"); QQmlApplicationEngine engine; engine.addImportPath(QStringLiteral("..\\..\\..\\..\\Tools\\Qt\\5.12.0\\x64\\5.12.0\\msvc2017_64\\qml")); engine.load(QUrl(QStringLiteral("../../Inc/miniModel/miniModel.qml"))); printf("======================================================================\n=\t\t\tTEST MINIMODEL INITIALISATION ENDED\t\t\t=\n======================================================================\n\n"); return app.exec(); }
note that main.qml is there :
SECRET\TEST_VIEW4\QML\miniModel
My exe is there
SECRET\TEST_VIEW4\Bin\x64\Debug
the qml source files are there
SECRET\Tools\Qt\5.12.0\x64\5.12.0\msvc2017_64\qml
etc.
I am not working with a QtCreator projet. I use a visual studio solution without the Qt Plugin. Maybe the problem comes form there ?
i would like to use this synthax for the paths "..\..\..\QML\miniModel" to go back to the main folder of the project and then specify the folder where miniModel.h is storedWhat should I write in the qml or c++ to use miniModel ? how can I specifie the path ?
I hope my question is clear, don't hesitate to ask for more details. Thanks for reading -
wrote on 10 May 2019, 14:25 last edited by
@Quentin91 IWhat I would suggest is before you go with such a complicated folder structure, create a test app with minimal QML files in the same directory and make sure that it works fine.
Also, make sure that whatever the path which you are referring to is correctly readable/accessible by the Qt classes.
-
@Quentin91 IWhat I would suggest is before you go with such a complicated folder structure, create a test app with minimal QML files in the same directory and make sure that it works fine.
Also, make sure that whatever the path which you are referring to is correctly readable/accessible by the Qt classes.
wrote on 13 May 2019, 08:04 last edited by Quentin91@Mammamia thanks for your answer. I started it but it's definitely taking too long as I use visual studio without Qt. Creating a new solution, writing the batch files to set the environment, add all the dll etc... it takes hours to make everything to work.
What I just need is : How can I specify the path there
import QtQuick.controls 2.5 import "../../x64/Debug"anothertry.miniModel 1.0 import "../../Src/" 1.0//File or directory not found import "../../x64/Debug/TEST_VIEW4.tlog" anothertry.minimodel 1.0;//symbol waited ";" import anothertry.miniModel 1.0//QML module not found ApplicationWindow {
qmlRegisterType<MiniModel>("miniModel", 1, 0, "MiniModel");
i'm new to QML and just don't know how to deal with it. I struggle to find some information about it. It's probably too obvious...
-
@Mammamia thanks for your answer. I started it but it's definitely taking too long as I use visual studio without Qt. Creating a new solution, writing the batch files to set the environment, add all the dll etc... it takes hours to make everything to work.
What I just need is : How can I specify the path there
import QtQuick.controls 2.5 import "../../x64/Debug"anothertry.miniModel 1.0 import "../../Src/" 1.0//File or directory not found import "../../x64/Debug/TEST_VIEW4.tlog" anothertry.minimodel 1.0;//symbol waited ";" import anothertry.miniModel 1.0//QML module not found ApplicationWindow {
qmlRegisterType<MiniModel>("miniModel", 1, 0, "MiniModel");
i'm new to QML and just don't know how to deal with it. I struggle to find some information about it. It's probably too obvious...
@Quentin91
I don't use VS, but I had some troubles with imports from folders that aren't subfolders as well.https://forum.qt.io/topic/98165/import-with-relative-path/6
Also, I never tried it, but are you sure QML import actually accepts
\\
as valid path ? Usually its/
on all platforms -
@Quentin91
I don't use VS, but I had some troubles with imports from folders that aren't subfolders as well.https://forum.qt.io/topic/98165/import-with-relative-path/6
Also, I never tried it, but are you sure QML import actually accepts
\\
as valid path ? Usually its/
on all platformswrote on 13 May 2019, 09:16 last edited by Quentin91@J.Hilk Thank you very much
You're right, the path is not correctly written. I'll update the answer.
i looked at the link you added, but my problem is not about importing a module, but about importing a new type defined in C++.
I tried to add a path because I'm desperate but usually, people just do that/*c++*/qmlRegisterType<MiniModel>("anothertry.miniModel", 1, 0, "MiniModel"); /*qml*/import anothertry.minimodel 1.0 //but for me, QML module not found
What's going on ? In what file or where is the new type specified after the project is built ?
-
@J.Hilk Thank you very much
You're right, the path is not correctly written. I'll update the answer.
i looked at the link you added, but my problem is not about importing a module, but about importing a new type defined in C++.
I tried to add a path because I'm desperate but usually, people just do that/*c++*/qmlRegisterType<MiniModel>("anothertry.miniModel", 1, 0, "MiniModel"); /*qml*/import anothertry.minimodel 1.0 //but for me, QML module not found
What's going on ? In what file or where is the new type specified after the project is built ?
@Quentin91 said in qmlRegisterType => QML module not found. How to specify the path to the object ?:
What's going on ? In what file or where is the new type specified ?
I usually do that in main.cpp right before the instance of QQmlApplicationEngine is created.
-
wrote on 13 May 2019, 09:57 last edited by
Actually, what I'm trying to do is communicating with an already made QML code using this pattern :
InternalItems.EditGrid { objectName: "EditGrid" width: widthScene*scale height: heightScene*scale opacity: 0.2 z: 1000 visible: mainModel.gridVisible && mainModel.edition //this resolution: mainModel.gridResolution //or this }
I don't really care about using qmlRegisterType ou my c++ class as a contextProperty with Q_INVOKABLE getters. I just want to be able too give the QML what it asks by mainModel.something. If you do have any recommendation or advice, don't hesitate.
(protip : when
/*c++*/engine.rootContext()->setContextProperty("mainModel", &mainModel);
/*c++*/Q_INVOKABLE double MainModelView::get_scale(void){ return _scale; }
/*qml*/ property real scale: mainModel.get_scale
it's said unable to assign [undefined] to double
-
wrote on 13 May 2019, 14:28 last edited by
@Quentin91 said in qmlRegisterType => QML module not found. How to specify the path to the object ?:
it's said unable to assign [undefined] to double
property real scale: mainModel.get_scale()
Q_INVOKABLE means you call it like a function. Does adding the () help?
-
@Quentin91 said in qmlRegisterType => QML module not found. How to specify the path to the object ?:
it's said unable to assign [undefined] to double
property real scale: mainModel.get_scale()
Q_INVOKABLE means you call it like a function. Does adding the () help?
-
wrote on 13 May 2019, 14:46 last edited by fcarney
Wait, where did you specify Q_INVOKABLE? It needs to be in the class definition, not in the cpp file.
So in your class:
class MainModelView { ... public: Q_INVOKABLE double get_scale(void); ... };
-
Wait, where did you specify Q_INVOKABLE? It needs to be in the class definition, not in the cpp file.
So in your class:
class MainModelView { ... public: Q_INVOKABLE double get_scale(void); ... };
wrote on 13 May 2019, 15:22 last edited by Quentin91@fcarney in both the declarations and definitions... I'll try to delete the Q_INVOKABLE from the cpp
Same error. The presence of the Q_INVOKABLE at the beginning of the definition doesn't change anything.
Unable to assign [undefined] to double -
wrote on 13 May 2019, 15:41 last edited by
I would backup and create a test project with the smallest amount of code. Then share that so we can see what is going on. If I run into something that "should work" I create test projects and test those out. Usually I either find the problem, or have an easy way to show others that there is indeed a problem. There are a lot of things that could cause objects to not be defined at the proper time. Making a minimal example helps other people help you.
-
@fcarney in both the declarations and definitions... I'll try to delete the Q_INVOKABLE from the cpp
Same error. The presence of the Q_INVOKABLE at the beginning of the definition doesn't change anything.
Unable to assign [undefined] to double@Quentin91
can you share some more code? preferable something compileable so we can take a closer look at it ;-) -
wrote on 14 May 2019, 09:42 last edited by Quentin91
@J.Hilk said in qmlRegisterType => QML module not found. How to specify the path to the object ?:
@Quentin91
can you share some more code? preferable something compileable so we can take a closer look at it ;-)@fcarney said in qmlRegisterType => QML module not found. How to specify the path to the object ?:
I would backup and create a test project with the smallest amount of code. Then share that so we can see what is going on. If I run into something that "should work" I create test projects and test those out. Usually I either find the problem, or have an easy way to show others that there is indeed a problem. There are a lot of things that could cause objects to not be defined at the proper time. Making a minimal example helps other people help you.
Thank you very much for your help
Ok, i made a new project in my solution. All the source, header and qml files are in the base folder. Only the executable is in a bin folder.
before showing the code, here are the problems. First, when I import my c++ type at the beginning of the qml, QML module not found but I still can launch the program with this error. When I use my type, Error : cannot assign [undefined] to bool
Here is miniModel.h
#ifndef _MINIMODEL_H_ #define _MINIMODEL_H_ #include <stdlib.h> #include <stdio.h> #include <iostream> #include <string> #include <QtGui/qguiapplication.h> #include <QtQml/qqmlcontext.h> #include <QtQml/qqmlapplicationengine.h> #include <QtCore/qdebug.h> #include <QtCore/qobject.h> #include <QtCore/qvariant.h> class MiniModel : public QObject { Q_OBJECT Q_PROPERTY(bool miniboule READ getMiniboule WRITE setMiniboule NOTIFY minibouleChanged) public: MiniModel(); bool getMiniboule(); void setMiniboule(bool bouboule); public slots: signals: void minibouleChanged(); private: bool m_miniboule; }; #endif
here is miniModel.cpp
#include "miniModel.h" MiniModel::MiniModel():m_miniboule(true) { } bool MiniModel::getMiniboule() { return m_miniboule; } void MiniModel::setMiniboule(bool bouboule){ m_miniboule = bouboule; emit minibouleChanged(); }
main.cpp
#include "miniModel.h" int main(int argc=0, char* argv[]=nullptr) { QGuiApplication app(argc, argv); qmlRegisterType<MiniModel>("myModel.miniModel", 1, 0, "MiniModel"); QQmlApplicationEngine engine; engine.addImportPath(QStringLiteral("..\\..\\..\\..\\Tools\\Qt\\5.12.0\\x64\\5.12.0\\msvc2017_64\\qml")); engine.load(QUrl(QStringLiteral("..\\..\\..\\miniModel.qml"))); return app.exec(); }
QML code
import QtQuick 2.5 import QtQuick.Window 2.5 import QtQuick.Controls 1.4 import myModel.miniModel 1.0//QML module not found ApplicationWindow { id: root width: 300 height: 480 Text{ id: textTest x: 62 y: 75 color: "#d21616" text: "vanilla" visible: false } MouseArea{ onClicked: testText.visible= MiniModel.getMiniboule//the boolean I want to acess, defined to true } }
-
couple of things, that cause this error.
First of,
MiniModel
is not a Signelton nor a context property but a registered type.So you'll have to instantiate the type in your QML code
ApplicationWindow { id: root width: 300 height: 480 visible:true Text{ id: testText x: 62 y: 75 color: "#d21616" text: "vanilla" visible: false } MiniModel{ id:mModel } MouseArea{ anchors.fill: parent onClicked: testText.visible= mModel.miniboule } }
Secondly, getMiniboule() is the getter function for the miniboule property. You're not supposed to call that manually, but rather let the property system handle that:
Q_PROPERTY(bool miniboule READ getMiniboule WRITE setMiniboule NOTIFY minibouleChanged) miniboule -> property name in QML getMiniboule -> c++ getter function name setMiniboule -> c++ setter function name ----- //in QML set value mModel.miniboule = true //read the value var a = mModel.miniboule
-
couple of things, that cause this error.
First of,
MiniModel
is not a Signelton nor a context property but a registered type.So you'll have to instantiate the type in your QML code
ApplicationWindow { id: root width: 300 height: 480 visible:true Text{ id: testText x: 62 y: 75 color: "#d21616" text: "vanilla" visible: false } MiniModel{ id:mModel } MouseArea{ anchors.fill: parent onClicked: testText.visible= mModel.miniboule } }
Secondly, getMiniboule() is the getter function for the miniboule property. You're not supposed to call that manually, but rather let the property system handle that:
Q_PROPERTY(bool miniboule READ getMiniboule WRITE setMiniboule NOTIFY minibouleChanged) miniboule -> property name in QML getMiniboule -> c++ getter function name setMiniboule -> c++ setter function name ----- //in QML set value mModel.miniboule = true //read the value var a = mModel.miniboule
wrote on 14 May 2019, 13:27 last edited by Quentin91@J.Hilk ok, I see, thank you very much ! so I have to use another way to communicate...
i don't want to instanciate my type in the QML. My job is to transform a QML python application into C ++ QML. And the QML I will use does not instanciate the types.
This is an extract of the python codemodule = importlib.import_module('models.'+self.model_file) self.main_model = module.MainModel( self ) self.rootContext().setContextProperty( 'mainModel', self.main_model ) self.statusChanged.connect( self.main_model.onStatusViewChanged )
So I thought I had to use setContextProperty in C++ too. Should I use a singleton instead ? If so, I tried. There it is :
I followed the example of the doc here https://doc.qt.io/qt-5/qtqml-cppintegration-definetypes.html
miniModel.h (the singleton)
#ifndef _MINIMODEL_H_ #define _MINIMODEL_H_ #include <stdlib.h> #include <stdio.h> #include <iostream> #include <string> #include <QtGui/qguiapplication.h> #include <QtQml/qqmlcontext.h> #include <QtQml/qqmlapplicationengine.h> #include <QtCore/qdebug.h> #include <QtCore/qobject.h> #include <QtCore/qvariant.h> class MiniModel : public QObject { Q_OBJECT Q_PROPERTY(bool miniboule READ miniboule WRITE setMiniboule NOTIFY minibouleChanged) public: MiniModel(); bool miniboule(); void setMiniboule(bool bouboule); signals: void minibouleChanged(); private: bool m_miniboule; }; #endif
miniModel.cpp
#include "miniModel.h" MiniModel::MiniModel():m_miniboule(true) { } bool MiniModel::miniboule() { return m_miniboule; } void MiniModel::setMiniboule(bool bouboule){ m_miniboule = bouboule; emit minibouleChanged(); }
main.cpp v1 : singleton using a QObject
#include "miniModel.h" //defining a miniModel instance as a singleton static QObject* mp_singleton(QQmlEngine* engine, QJSEngine* scriptEngine) { Q_UNUSED(engine) Q_UNUSED(scriptEngine) MiniModel* miniSingleton = new MiniModel(); return miniSingleton; } int main(int argc=0, char* argv[]=nullptr) { printf("\n launching \n"); QGuiApplication app(argc, argv); qmlRegisterSingletonType<MiniModel>("myModel.miniModel", 1, 0, "MiniModel",mp_singleton); QQmlApplicationEngine engine; engine.addImportPath(QStringLiteral("..\\..\\..\\..\\Tools\\Qt\\5.12.0\\x64\\5.12.0\\msvc2017_64\\qml")); engine.load(QUrl(QStringLiteral("..\\..\\..\\miniModel.qml"))); return app.exec(); }
main.cpp v2 : singletin using QJSValue
#include "miniModel.h" static QJSValue m_singletonModel(QQmlEngine* engine, QJSEngine* scriptEngine) { Q_UNUSED(engine) static bool m_miniboule; QJSValue miniModel = scriptEngine->newObject(); miniModel.setProperty("miniboule", m_miniboule); return miniModel; } int main(int argc = 0, char* argv[] = nullptr) { printf("\n launching \n"); QGuiApplication app(argc, argv); qmlRegisterSingletonType("myModel.miniModel", 1, 0, "MiniModel", m_singletonModel); QQmlApplicationEngine engine; engine.addImportPath(QStringLiteral("..\\..\\..\\..\\Tools\\Qt\\5.12.0\\x64\\5.12.0\\msvc2017_64\\qml")); engine.load(QUrl(QStringLiteral("..\\..\\..\\miniModel.qml"))); return app.exec(); }
and the QML. be careful, it's tough
import QtQuick 2.5 import QtQuick.Window 2.5 import QtQuick.Controls 1.4 import myModel.miniModel 1.0 as MyModel ApplicationWindow { id: root width: 300 height: 480 visible:true Text{ id: textTest x: 62 y: 75 color: "#d21616" text: "vanilla" visible: false//the text is supposed to appear when clicking in the mouseArea } MouseArea{ anchors.fill: parent onClicked: textTest.visible= MyModel.Minimodel.miniboule//the boolean I want to acess, defined to true } }
now, the error changed, since I called MyModel.MiniModel.miniboule instead of just MiniModel.miniboule
the error is TypeError: Cannot read property 'miniboule' of undefinedps : the topic is now the same than this one. I made another topic for another error, but the errors are actually linked (or the same) : https://forum.qt.io/topic/102730/error-cannot-assign-undefined-to-qstring-while-communicating-between-c-and-qml
-
wrote on 14 May 2019, 14:42 last edited by
@Quentin91 said in qmlRegisterType => QML module not found. How to specify the path to the object ?:
import myModel.miniModel 1.0 as MyModel
The way you have written this MyModel is the MiniModel.
So you should be accessing miniboule like this:onClicked: textTest.visible= MyModel.miniboule
-
@Quentin91 said in qmlRegisterType => QML module not found. How to specify the path to the object ?:
import myModel.miniModel 1.0 as MyModel
The way you have written this MyModel is the MiniModel.
So you should be accessing miniboule like this:onClicked: textTest.visible= MyModel.miniboule
wrote on 14 May 2019, 15:35 last edited byonClicked: textTest.visible= MyModel.miniboule
When I write it this way, the error is cannot assign [undefined] to bool
Else, when writing MyModel.MiniModel.miniboule, it says ContentItem: Binding loop detected for property "implicitWidth but it works !It's been three days that I'm working on that version, singleton, all day and I have no idea why it works only now... but anyway, thank you very much for your help !
-
onClicked: textTest.visible= MyModel.miniboule
When I write it this way, the error is cannot assign [undefined] to bool
Else, when writing MyModel.MiniModel.miniboule, it says ContentItem: Binding loop detected for property "implicitWidth but it works !It's been three days that I'm working on that version, singleton, all day and I have no idea why it works only now... but anyway, thank you very much for your help !
//main.cpp #include <QApplication> #include <QQmlApplicationEngine> #include "minimodel.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); QQmlApplicationEngine engine; MiniModel mModel; engine.rootContext()->setContextProperty("MiniModel", &mModel); engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); if (engine.rootObjects().isEmpty()) return -1; return app.exec(); }
//main.qml import QtQuick 2.5 import QtQuick.Window 2.5 import QtQuick.Controls 1.4 ApplicationWindow { id: root width: 300 height: 480 visible:true Text{ id: testText x: 62 y: 75 color: "#d21616" text: "vanilla" visible: false } MouseArea{ anchors.fill: parent onClicked: testText.visible= MiniModel.miniboule } }
works fine
1/19