Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. qmlRegisterType fails when Name does not match type

qmlRegisterType fails when Name does not match type

Scheduled Pinned Locked Moved Solved QML and Qt Quick
10 Posts 3 Posters 1.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • fcarneyF Offline
    fcarneyF Offline
    fcarney
    wrote on last edited by fcarney
    #1

    Hello,
    I am not sure if this is a bug or a feature. Considering the following code:
    main.cpp:

    #include <QObject>
    #include <QQmlContext>
    #include <QQmlListProperty>
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    
    #include "testclasses.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);    
    
        // access to new type
        qmlRegisterType<TestObj>("TestClasses", 1, 0, "TestObj");
    
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
    
        // access to object
        TestCon testcon;
        engine.rootContext()->setContextProperty("testcon", &testcon);
    
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
    
        return app.exec();
    }
    

    testclasses.h:

    #ifndef TESTCLASSES_H
    #define TESTCLASSES_H
    
    #include <QObject>
    #include <QQmlListProperty>
    
    class TestObj: public QObject
    {
        Q_OBJECT
    
    public:
        TestObj(){}
    };
    
    class TestCon: public QObject
    {
        Q_OBJECT
    
        Q_PROPERTY(QQmlListProperty<TestObj> oLists READ oLists)
    
    public:
        TestCon(){
            m_olist.append(new TestObj());
            m_olist.append(new TestObj());
            m_olist.append(new TestObj());
        }
    
        QQmlListProperty<TestObj> oLists()
        {
            return  QQmlListProperty<TestObj>(this, m_olist);
        }
    
    private:
        QList<TestObj*> m_olist;
    };
    
    #endif // TESTCLASSES_H
    

    main.qml:

    import QtQuick 2.9
    import QtQuick.Window 2.2
    
    import TestClasses 1.0
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Test Export List")
    
        Component.onCompleted:{
            console.log(testcon.oLists)
            console.log(testcon.oLists[0])
    
            console.log("Startup Complete")
    
            //testcon.oLists.append(new TestObj())
        }
    }
    

    If TestObj is not named "TestObj" in the registration call then it fails to register. Worse is if it appears to register it can cause the object to appear as a QVariant(QQmlListProperty<TestObj>) in QML. I ran into this in a large codebase and tried to reproduce. Changing the name to match the object name did fix the issue for the big codebase.

    This works:

    qmlRegisterType<TestObj>("TestClasses", 1, 0, "TestObj");
    

    This fails:

    qmlRegisterType<TestObj>("TestClasses", 1, 0, "crapobject");
    

    I am not sure this is desired behavior or not. Is this supposed to fail?

    System:
    Windows 10 Pro 64 bit x86 (Intel)
    Qt 5.9.7
    mingw 5.3.0 compiler

    Edit:
    I believe this person had the same issue:
    qml-and-qvariant-qobjectlist

    C++ is a perfectly valid school of magic.

    raven-worxR 1 Reply Last reply
    0
    • fcarneyF Offline
      fcarneyF Offline
      fcarney
      wrote on last edited by
      #2

      Ooh, I got my test program to produce the QVariant wrapped version:

      qmlRegisterType<TestCon>("TestClasses", 1, 0, "TestCon");
      qmlRegisterType<TestObj>("TestClasses", 1, 0, "tObj");
      

      This produces the object:

      QVariant(QQmlListProperty<TestObj>)
      

      That is the weird one where is "sort of" works.

      C++ is a perfectly valid school of magic.

      1 Reply Last reply
      0
      • dheerendraD Offline
        dheerendraD Offline
        dheerendra
        Qt Champions 2022
        wrote on last edited by
        #3

        Not very clear what is not working for you. Simply registering the TestObj with tObj should work.

        qmlRegisterType<TestObj>("TestClasses", 1, 0, "tObj");
        

        Do you mean to say that it is working only if you do the following ?

        qmlRegisterType<TestCon>("TestClasses", 1, 0, "TestCon");
        

        Dheerendra
        @Community Service
        Certified Qt Specialist
        http://www.pthinks.com

        1 Reply Last reply
        0
        • fcarneyF Offline
          fcarneyF Offline
          fcarney
          wrote on last edited by fcarney
          #4

          @dheerendra
          Correct. If the object name TestObj does not match the name text (last parameter) the behavior is that it will either fail, or if another object is already registered with "TestClasses", produce the desired object wrapped in a QVariant. I think this may be something newer versions of Qt have introduced. The code I am working with worked fine on older versions of Qt. We are now on the LTS versions 5.9.

          Edit:
          Note, it fails when accessing the list object being exported to QML. So it fails here in the QML:

          console.log(testcon.oLists)
          console.log(testcon.oLists[0])
          

          C++ is a perfectly valid school of magic.

          1 Reply Last reply
          0
          • dheerendraD Offline
            dheerendraD Offline
            dheerendra
            Qt Champions 2022
            wrote on last edited by
            #5

            I have tried with Qt 5.11.x and 5.9.x. It is working without any issue. Do you have complete sample to check your issue ?

            Dheerendra
            @Community Service
            Certified Qt Specialist
            http://www.pthinks.com

            1 Reply Last reply
            0
            • fcarneyF Offline
              fcarneyF Offline
              fcarney
              wrote on last edited by fcarney
              #6

              I filed a bug report here. You can get the zip file with the entire project in there. It provides #defines to enable each CASE one at a time to illustrate the problem:
              https://bugreports.qt.io/browse/QTBUG-71827

              Edit:
              I had to reupload the project again to the bug report. The qml file had the check function commented out. It did not easily show the problem. Also, I just tested on Qt 5.11.2 and it complains about the object name not being uppercase but still produces the QVariant wrapped object in CASE 2.

              C++ is a perfectly valid school of magic.

              1 Reply Last reply
              0
              • fcarneyF Offline
                fcarneyF Offline
                fcarney
                wrote on last edited by
                #7

                I added one more test case:

                #ifdef CASE4
                    qmlRegisterType<TestCon>("TestClasses", 1, 0, "TestCon");
                    qmlRegisterType<TestObj>("TestClasses", 1, 0, "Badobject");
                #endif
                

                This works correctly. It is not the name matching that matters, but that the name must be uppercase on the first letter. Strange requirement.

                C++ is a perfectly valid school of magic.

                1 Reply Last reply
                0
                • dheerendraD Offline
                  dheerendraD Offline
                  dheerendra
                  Qt Champions 2022
                  wrote on last edited by
                  #8

                  Yes, QML components have to start with Capital Letter. That is the requirement.

                  Dheerendra
                  @Community Service
                  Certified Qt Specialist
                  http://www.pthinks.com

                  1 Reply Last reply
                  1
                  • fcarneyF fcarney

                    Hello,
                    I am not sure if this is a bug or a feature. Considering the following code:
                    main.cpp:

                    #include <QObject>
                    #include <QQmlContext>
                    #include <QQmlListProperty>
                    #include <QGuiApplication>
                    #include <QQmlApplicationEngine>
                    
                    #include "testclasses.h"
                    
                    int main(int argc, char *argv[])
                    {
                        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);    
                    
                        // access to new type
                        qmlRegisterType<TestObj>("TestClasses", 1, 0, "TestObj");
                    
                        QGuiApplication app(argc, argv);
                    
                        QQmlApplicationEngine engine;
                    
                        // access to object
                        TestCon testcon;
                        engine.rootContext()->setContextProperty("testcon", &testcon);
                    
                        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                        if (engine.rootObjects().isEmpty())
                            return -1;
                    
                        return app.exec();
                    }
                    

                    testclasses.h:

                    #ifndef TESTCLASSES_H
                    #define TESTCLASSES_H
                    
                    #include <QObject>
                    #include <QQmlListProperty>
                    
                    class TestObj: public QObject
                    {
                        Q_OBJECT
                    
                    public:
                        TestObj(){}
                    };
                    
                    class TestCon: public QObject
                    {
                        Q_OBJECT
                    
                        Q_PROPERTY(QQmlListProperty<TestObj> oLists READ oLists)
                    
                    public:
                        TestCon(){
                            m_olist.append(new TestObj());
                            m_olist.append(new TestObj());
                            m_olist.append(new TestObj());
                        }
                    
                        QQmlListProperty<TestObj> oLists()
                        {
                            return  QQmlListProperty<TestObj>(this, m_olist);
                        }
                    
                    private:
                        QList<TestObj*> m_olist;
                    };
                    
                    #endif // TESTCLASSES_H
                    

                    main.qml:

                    import QtQuick 2.9
                    import QtQuick.Window 2.2
                    
                    import TestClasses 1.0
                    
                    Window {
                        visible: true
                        width: 640
                        height: 480
                        title: qsTr("Test Export List")
                    
                        Component.onCompleted:{
                            console.log(testcon.oLists)
                            console.log(testcon.oLists[0])
                    
                            console.log("Startup Complete")
                    
                            //testcon.oLists.append(new TestObj())
                        }
                    }
                    

                    If TestObj is not named "TestObj" in the registration call then it fails to register. Worse is if it appears to register it can cause the object to appear as a QVariant(QQmlListProperty<TestObj>) in QML. I ran into this in a large codebase and tried to reproduce. Changing the name to match the object name did fix the issue for the big codebase.

                    This works:

                    qmlRegisterType<TestObj>("TestClasses", 1, 0, "TestObj");
                    

                    This fails:

                    qmlRegisterType<TestObj>("TestClasses", 1, 0, "crapobject");
                    

                    I am not sure this is desired behavior or not. Is this supposed to fail?

                    System:
                    Windows 10 Pro 64 bit x86 (Intel)
                    Qt 5.9.7
                    mingw 5.3.0 compiler

                    Edit:
                    I believe this person had the same issue:
                    qml-and-qvariant-qobjectlist

                    raven-worxR Offline
                    raven-worxR Offline
                    raven-worx
                    Moderators
                    wrote on last edited by
                    #9

                    @fcarney said in qmlRegisterType fails when Name does not match type:

                    This fails:
                    qmlRegisterType<TestObj>("TestClasses", 1, 0, "crapobject");

                    QML type names always must begin with a capital letter.
                    Is this your issue?

                    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                    If you have a question please use the forum so others can benefit from the solution in the future

                    1 Reply Last reply
                    0
                    • fcarneyF Offline
                      fcarneyF Offline
                      fcarney
                      wrote on last edited by
                      #10

                      Yes, the issue is the requirement of the upper case letter at the beginning.

                      The original issue is that it had worked in an older version of Qt and then when upgrading to 5.9.7 it started displaying this behavior. It was not obvious what the problem was. I did observe that in 5.11.2 it now complains and says it needs a capital letter at the beginning so at least there is a way to track it down in later versions.

                      Thanks for everyone's help!

                      C++ is a perfectly valid school of magic.

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved