qmlRegisterType => QML module not found. How to specify the path to the object ?



  • 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 stored

    What 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



  • @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.



  • @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...


  • Moderators

    @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



  • @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 ?


  • Moderators

    @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.



  • 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



  • @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 function

    nice 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.


  • Moderators

    @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
        }
    }
    

  • Moderators

    @Quentin91

    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 code

    module = 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 undefined

    ps : 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
    


  • @fcarney

    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 !


  • Moderators

    @Quentin91

    //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


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.