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. Custom QQuickItem : access in C++
Forum Updated to NodeBB v4.3 + New Features

Custom QQuickItem : access in C++

Scheduled Pinned Locked Moved Solved QML and Qt Quick
5 Posts 2 Posters 1.8k 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.
  • B Offline
    B Offline
    BuzzLEitinho
    wrote on last edited by
    #1

    Hello
    I realize there is an wonderful doc about accessing QML elements from C++ in Qt
    http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html#accessing-loaded-qml-objects-by-object-name

    But I have a different problem.
    I am extending QAbstractListModel and within one of the type of items that I use in the models, I sometimes, instantiate a custom QML QuickItem.
    So, this QML item (which has a custom C++ class object in runtime) is directly associated with the model item at a certain index. I can "communicate" with the model item through some Q_PROPERTY binding signals, that change properties in QML, and then BACK to the model item through some roles. But this is SO overkill and heavy, it would be MUCH better if I didn't meddle with QML and emiited some signals directly between C++ objects.

    So, I was wondering how I could access this custom class object within the model item in C++. That way, I could make some connects, and emit some signals, without QML interfering between.

    Thank you

    J.HilkJ 1 Reply Last reply
    0
    • B BuzzLEitinho

      Hello
      I realize there is an wonderful doc about accessing QML elements from C++ in Qt
      http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html#accessing-loaded-qml-objects-by-object-name

      But I have a different problem.
      I am extending QAbstractListModel and within one of the type of items that I use in the models, I sometimes, instantiate a custom QML QuickItem.
      So, this QML item (which has a custom C++ class object in runtime) is directly associated with the model item at a certain index. I can "communicate" with the model item through some Q_PROPERTY binding signals, that change properties in QML, and then BACK to the model item through some roles. But this is SO overkill and heavy, it would be MUCH better if I didn't meddle with QML and emiited some signals directly between C++ objects.

      So, I was wondering how I could access this custom class object within the model item in C++. That way, I could make some connects, and emit some signals, without QML interfering between.

      Thank you

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #2

      Hi @BuzzLEitinho ,
      I would say that this highly depends on your implementation.

      is your custom QML QuickItem initated purly on the QML-Side, or do you have an existing Object in your main.cpp ?

      If you have, than you can do normal connects between existing classes inside the main.cpp. But, because main.cpp is not derived from QObject you'll have to reference it directly:

      //main.cpp
      {
      
      myClass1 mC1;
      myClass2 mC2;
      
      QObject::connect(&mC1, &myClass1::mySignal, &mC2, & myClass2::mySlot);
      

      if not, you should be able to connecct them directly inside QMl as well, the most minimal way I guess.

      Connections{
          target: myCppBackend1
      
          onSignal:myCppBackend2.mySlot(value)
      }
      

      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      1 Reply Last reply
      0
      • B Offline
        B Offline
        BuzzLEitinho
        wrote on last edited by
        #3

        It is initiated purely on QML-Side, because it is used as a Loader source item, which in turn is inside a repeater with another custom classed derived from QAbstractListModel as the repeater model.

        About the second solution, two points:
        1- How do I access the cpp target?
        2- It is still not ideal. The perfect solution would be a direct connection without QML. Like so:

        QObject::connect(&modelItem, SIGNAL(messageReady), &customQQuickItem, SLOT(onMessageReady));
        

        I obviously have access to the model item, anytime, because I have access to the model (the custom derived QAbstractListModel class). But the problem here is customQQuickItem. I know it exists, because if I place a breakpoint in the constructor, or in the setter of a Q_PROPERTY variable, it works properly. The fact that customQQuickItem is used in QML, it builds it under C++. Because I register a type with:
        qmlRegisterType<customQQuickItem>("CustomGeometry", 1, 0, "customQQuickItem");
        And everytime I create a customQQuickItem in QML, it also creates its "brother instance" in c++. The problem, is access, pointer access, to this "brother instance"

        J.HilkJ 1 Reply Last reply
        0
        • B BuzzLEitinho

          It is initiated purely on QML-Side, because it is used as a Loader source item, which in turn is inside a repeater with another custom classed derived from QAbstractListModel as the repeater model.

          About the second solution, two points:
          1- How do I access the cpp target?
          2- It is still not ideal. The perfect solution would be a direct connection without QML. Like so:

          QObject::connect(&modelItem, SIGNAL(messageReady), &customQQuickItem, SLOT(onMessageReady));
          

          I obviously have access to the model item, anytime, because I have access to the model (the custom derived QAbstractListModel class). But the problem here is customQQuickItem. I know it exists, because if I place a breakpoint in the constructor, or in the setter of a Q_PROPERTY variable, it works properly. The fact that customQQuickItem is used in QML, it builds it under C++. Because I register a type with:
          qmlRegisterType<customQQuickItem>("CustomGeometry", 1, 0, "customQQuickItem");
          And everytime I create a customQQuickItem in QML, it also creates its "brother instance" in c++. The problem, is access, pointer access, to this "brother instance"

          J.HilkJ Offline
          J.HilkJ Offline
          J.Hilk
          Moderators
          wrote on last edited by J.Hilk
          #4

          @BuzzLEitinho

          ok, a somewhat complexer example to the 2nd solution, hopefully.

          assuming 2 localy (in QML) created Items with cpp-part:

          qmlRegisterType<customQQuickItem>("CustomGeometry", 1, 0, "customQQuickItem");
          qmlRegisterType<otherObject>("OtherObject", 1, 0, "otherObject");
          

          than you should be able to connect signal and slots this way:

          #import CustomGeometry 1.0
          #import OtherObject 1.0
          
          CustomGeometry{
              id: obj1
          }
          
          OtherObject{
             id: obj2
          }
          
          Connections{
              target: obj1//The signal emitter
          
             onMySignal: obj2.mySlot(value) // Qml signal catch to the cpp Signal `mySignal(int value)`
          }
          

          if the otherObject is context Property, that makes the connection a bit easier:

          //main.cpp
          otherObject obj2;
          
          QQmlApplicationEngine engine;
          engine.rootContext()->setContextProperty("obj2", &otherObject);
          
          //QML part
          CustomGeometry{
              id: obj1
              onMySignal: obj2.mySlot(value)
          }
          
          //everything else from the other example can be droped, as obj2 is a "global root property"
          

          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          1 Reply Last reply
          0
          • B Offline
            B Offline
            BuzzLEitinho
            wrote on last edited by BuzzLEitinho
            #5

            Thank you for the effort.

            The problem is that this "otherObject" is not a QQuickItem, and I do not have a way to get it in QML. This "otherObject" is an item of the model itself.
            So there is no point in initializing it in QML, like you did with

            OtherObject{
               id: obj2
            }
            

            http://doc.qt.io/qt-5/model-view-programming.html#creating-new-models

            The ideal would be to get the pointer to the customQQuickItem instance in c++.
            I'm thinking about setting a role and pass "this" in QML to that role.
            That way I can access the instance in C++ side. But I'm not sure it would work... And I don't know how to access the current item in the model being built in QML side.

            Update: I can access the QQuickItem now.
            Though the method is not so covenient. Not something that I've seen, at least.
            In my modelItem, I keep a *customQQuickItem pointer. Set to null in constructor.
            Then, in QML:

            customQQuickItem {
                   id:customItem
                   Component.onCompleted: {
                        customItemRole = customItem 
                    }
            }
            

            Then, on the c++ side. The model handles the role, when QML sets it, and it updates the pointer.
            And now, I have access to the custom QQuickItem

            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