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. Invoke slot of child of child of QQmlPropertyMap?
Forum Updated to NodeBB v4.3 + New Features

Invoke slot of child of child of QQmlPropertyMap?

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
qml bindingqqmlpropertymap
3 Posts 2 Posters 662 Views 2 Watching
  • 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.
  • jwernernyJ Offline
    jwernernyJ Offline
    jwernerny
    wrote on last edited by
    #1

    [This is a duplicate of StackOverflow question I asked, but I am hoping it find a different audience with other solutions.]

    BTW, this is for a Qt 5.15 application.

    I am working on a design where I have a class (call it MyBaseClass) that inherits from QQmlPropertyMap. It implements some additional behaviors for my system which are then used by other classes that inerit from MyBaseClass (e.g. ChildClass).

    From QML, (QtQuick), I wish to invoke a slot (mySlot()) of ChildClass. When I try, I get the following issues in the Application Output (mentioning MyBaseClass) even though I am only using ChildClass.

    qrc:/main.qml:17: TypeError: Property 'mySlot' of object MyBaseClass(0x55f88ef86b50) is not a function
    qrc:/main.qml:24: TypeError: Property 'mySlot' of object MyBaseClass(0x55f88ef86b50) is not a function
    

    I also tried implementing sending signals from QML, but I get a similar issue trying to bind to the QML emitted signals. (I am not adding that example.)

    My "gut" says that the problem is I am not doing things the "Qt Way," but I can't figure out what it is.
    [I like to say "If you have to do a lot of work to make something work, you aren't doing it the 'Qt Way.'"]

    Does anyone know the Qt Way to do this? I almost at doing C++ Templates, but I'm not sure I can extend the functionality I want to add to MyBaseClass that way.

    I'm also not totally surprised noting there are some interesting ways you have to initialize a member inheriting directly from QQmlPropertyMap.

    Here is the minimum example code of the problem to demonstrate the problem. (I'm leaving out the .pro file since it is trivial to make.)

    MyBaseClass.h

    #include <QQmlPropertyMap>
    
    class MyBaseClass : public QQmlPropertyMap
    {
        Q_OBJECT
    public:
        explicit MyBaseClass(QObject *parent = nullptr)
            : QQmlPropertyMap(this, parent)
        {}
    
    };
    

    ChildClass.h

    #include "MyBaseClass.h"
    #include <QObject>
    #include <QDebug>
    
    class ChildClass : public MyBaseClass
    {
        Q_OBJECT
    public:
        ChildClass(QObject *parent = nullptr)
            : MyBaseClass(parent) {}
    
    public slots:
        void mySlot() {
            qDebug() << "This is mySlot";
        };
    };
    

    main.qml

    import QtQuick 2.15
    import QtQuick.Window 2.15
    
    
    Window {
        id: theMainWindow
        width: 640
        height: 480
        visible: true
        title: qsTr("Hello World")
    
        property QtObject   cData: childData;
    
        onCDataChanged: {
            childData.mySlot();
        }
    
        Timer { // wait a bit before calling
            repeat: false
            interval: 2000
            running: true
            onTriggered: childData.mySlot();
        }
    }
    

    main.cpp

    int main(int argc, char *argv[])
    {
    #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    #endif
    
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
    
        auto childData = new ChildClass();
    
        engine.rootContext()->setContextProperties({
            QQmlContext::PropertyPair{"childData",  QVariant::fromValue(childData)},
        });
        const QUrl url(QStringLiteral("qrc:/main.qml"));
        QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
            &app, [url](QObject *obj, const QUrl &objUrl) {
                if (!obj && url == objUrl)
                    QCoreApplication::exit(-1);
            }, Qt::QueuedConnection);
        engine.load(url);
    
        return app.exec();
    }
    
    1 Reply Last reply
    0
    • jeremy_kJ Offline
      jeremy_kJ Offline
      jeremy_k
      wrote on last edited by jeremy_k
      #2

      The answers at this time in the StackOverflow thread here are correct.
      The instantiation of template constructor for QQmlPropertyMap needs to know the derived type to register it. The template is being instantiated for MyBaseClass, and therefore the metaobject system recognizes that as the most derived type of ChildClass.

      Is the base class that inherits from QQmlPropertyMap, plus the derived class that inherits from the base necessary? Can the code be restructured to either directly inherit QQmlPropertyMap in ChildClass, or compose and expose the MyBaseClass instance as a property of ChildClass?

      Asking a question about code? http://eel.is/iso-c++/testcase/

      jwernernyJ 1 Reply Last reply
      0
      • jeremy_kJ jeremy_k

        The answers at this time in the StackOverflow thread here are correct.
        The instantiation of template constructor for QQmlPropertyMap needs to know the derived type to register it. The template is being instantiated for MyBaseClass, and therefore the metaobject system recognizes that as the most derived type of ChildClass.

        Is the base class that inherits from QQmlPropertyMap, plus the derived class that inherits from the base necessary? Can the code be restructured to either directly inherit QQmlPropertyMap in ChildClass, or compose and expose the MyBaseClass instance as a property of ChildClass?

        jwernernyJ Offline
        jwernernyJ Offline
        jwernerny
        wrote on last edited by
        #3

        @jeremy_k I'm now looking at a template based solution as suggested on the SO question (https://stackoverflow.com/a/65401996/447438). The ideas has been in my head for a couple of days, and the post pushed me to look more deeply into it.

        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