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. Unable to create qml component with C++ property passed as parameter

Unable to create qml component with C++ property passed as parameter

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
3 Posts 2 Posters 688 Views 1 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.
  • C Offline
    C Offline
    Cyrille de Brebisson
    wrote on last edited by
    #1

    Hello,

    I have a C++ signal that passes a C++ object (type registered with QML), and is caught by a QML component.
    This QML component,creates another QML component which must have this C++ object as a property.
    However, I am unable to make it work :-(

    I have tried 2 different things which you can see in the code bellow (I am not showing the C++ as it is insubstancial for the moment)

    So, what is the proper way to "connect" a QML component with an existing C++ object?

    ApplicationWindow {
    visible: true; width: 640; height: 480

    Component { // Test version 1: Does not work as the "text" property initialization generates an error
        id: myTabButton
        TabButton {
            property HPACDevice device
            id: button
            text: device.value.toString() // causes: "TypeError: Cannot read property 'value' of null"
        }
    }
    
    Component { // Test version 2: Does "work", but does not do what I want as I end up with 2 instances of HPACDevice
        id: myTabButton2
        TabButton {
            HPACDevice
            { id: device }
            id: button
            text: device.value.toString() // works, but I end up with 2 HPACDevice being instanciated!
        }
    }
    
    HPACgroup {
        id: group
        onNewDevice: { // respond to: void HPACgroup::newDevice(HPACDevice &device);
            myTabButton.createObject(row, {"device": device}); // test 1. Causes error
            myTabButton2.createObject(row, {"device": device}); // test 2: cause 2 instances of HPACDevice
        }
    }
    
    Column {
        id: row
        Button { // Just a button that tells the C++ group to add a device. In "real life", the devices will be created in reaction to OS events (USB Plugged detected in C++)
            width: 100; height: 100; text: "add"
            onClicked: group.addDevice() // Causes the C++ group create another "device".
        }
    }
    

    }

    Thanks,
    Cyrille

    1 Reply Last reply
    0
    • A Offline
      A Offline
      ambershark
      wrote on last edited by
      #2

      Here is how you create a C++ object and then use it in QML.

      You don't need to register the object either.

      #pragma once
       
      #include <QObject>
       
      class Foo : public QObject
      {
         Q_OBJECT
       
      public:
         explicit Foo(QObject *parent = nullptr) : QObject(parent) { }
         Q_INVOKABLE QString hello()
         {
            return "hello world";
         }
      };
      
      #include <QQmlApplicationEngine>
      #include <QQmlComponent>
      #include "foo.h"
       
      int main(int ac, char **av)
      {
          QApplication app(ac, av);
           
          // load qml engine and component
          auto eng = new QQmlApplicationEngine();
          auto comp = new QQmlComponent(eng, QUrl("qrc:///qml/main.qml"));
          auto obj = comp->create();
          if (!obj)
              return;
       
          // No registration required for this ...
          auto foo = new Foo();
          eng->rootContext()->setContextProperty("foo", foo);
       
          return app.exec();
      }
      

      And here is the QML:

      import QtQuick 2.11
      import com.ambershark.example.foo 1.0
       
      Rectangle {
          width: 300
          height: 300
       
          Text {
             text: qsTr("Click me")
             anchors.centerIn: parent
       
             MouseArea {
                anchors.fill: parent
                onClicked: { console.log(foo.hello())
             }
          }
      }
      

      My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

      C 1 Reply Last reply
      0
      • A ambershark

        Here is how you create a C++ object and then use it in QML.

        You don't need to register the object either.

        #pragma once
         
        #include <QObject>
         
        class Foo : public QObject
        {
           Q_OBJECT
         
        public:
           explicit Foo(QObject *parent = nullptr) : QObject(parent) { }
           Q_INVOKABLE QString hello()
           {
              return "hello world";
           }
        };
        
        #include <QQmlApplicationEngine>
        #include <QQmlComponent>
        #include "foo.h"
         
        int main(int ac, char **av)
        {
            QApplication app(ac, av);
             
            // load qml engine and component
            auto eng = new QQmlApplicationEngine();
            auto comp = new QQmlComponent(eng, QUrl("qrc:///qml/main.qml"));
            auto obj = comp->create();
            if (!obj)
                return;
         
            // No registration required for this ...
            auto foo = new Foo();
            eng->rootContext()->setContextProperty("foo", foo);
         
            return app.exec();
        }
        

        And here is the QML:

        import QtQuick 2.11
        import com.ambershark.example.foo 1.0
         
        Rectangle {
            width: 300
            height: 300
         
            Text {
               text: qsTr("Click me")
               anchors.centerIn: parent
         
               MouseArea {
                  anchors.fill: parent
                  onClicked: { console.log(foo.hello())
               }
            }
        }
        
        C Offline
        C Offline
        Cyrille de Brebisson
        wrote on last edited by
        #3

        Hello,

        Thanks, this is actually valuable information as I was trying to do something similar!

        However, it does not what I was trying to achieve here.
        What I was trying to achieve was the creation of a QML object in response to the creation of a C++ object, with said C++ object being a "typed property" of the QML object, not a global variable (of course, multiple such objects will be instantiated)

        One of the reason why I would like it to be a registered property is so that, in QML, I get dynamic completion and other development niceties.

        Cyrille

        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