Solved qmlRegisterType => QML module not found. How to specify the path to the object ?
-
@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?
-
@fcarney I already tried.
TypeError: property 'get_scale' of object NAMESPACE::MainModelView is not a functionnice try ;)
-
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); ... };
-
@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 -
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.
-
@Quentin91
can you share some more code? preferable something compileable so we can take a closer look at it ;-) -
@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
-
@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
-
@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
-
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