Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Propagating signals between qml files



  • I am trying to figure out the correct way to propagate a signal from the child of a child, too the grandparent. For instance, let's say I have something like the following setup:

    Grandparent
    {
      id: Grandpa
    }
    

    where Grandpa.qml is:

    Child
    {
      id: mom
    
      GrandChild
      {
         id: grandchild
      }
    }
    

    where GrandChild.qml has a signal:

    Oliver
    {
      id: root
      signal x
    }
    

    I know I can get x up to the grandparent by propagating that signal upwards like so:

    Child
    {
      id: mom
      signal x
    
      GrandChild
      {
         id: grandchild
          onX: mom.x()
      }
    }
    

    then creating a slot I can do some logic:

    Grandparent
    {
      id: Grandpa
      onX: //do something
    }
    

    but, that doesn't seem right to me. Is there an easier or "better" way of doing this in QML? Obviously, I could create a signal in C++, but I would rather not have the overhead if possible.



  • If a reference to the GrandChild object is available in Grandparent, Connections can be used.

    Child.qml

    Item {
        property alias grandchild: grandchild
        Item {
            id: grandchild
            signal ready
            Component.onCompleted: ready()
        }
    }
    
    Item {
        Child { id : child }
        Connections {
            target: child.children[0]
            onReady: console.log("anonymous grandchild ready")
        }
        Connections {
            target: child.grandchild
             onReady: console.log("named grandchild ready")
        }
    }
    

    As of Qt 5.15.0, there's a deprecation warning message indicating that Connection { onReady: code } should be written as Connections { function onReady() { code } }. I don't know if this works in earlier versions.



  • I don't know if there is an easier way to propagate signals across elements than going up and then down.

    I personally don't like global variables. So the only thing I can think of is that if the signal relates to some logical state/data between the elements, then the logical relation might not have anything to do with the visual relation and it might be really cumbersome to propagate the signal from source to destination in QML. In that scenario I recommend using a shared C++ model to represent that common logical state.

    By the way in your code snippet grandpa is an instantiation of mama. I think you meant to have mama be a child element of grandpa?



  • If a reference to the GrandChild object is available in Grandparent, Connections can be used.

    Child.qml

    Item {
        property alias grandchild: grandchild
        Item {
            id: grandchild
            signal ready
            Component.onCompleted: ready()
        }
    }
    
    Item {
        Child { id : child }
        Connections {
            target: child.children[0]
            onReady: console.log("anonymous grandchild ready")
        }
        Connections {
            target: child.grandchild
             onReady: console.log("named grandchild ready")
        }
    }
    

    As of Qt 5.15.0, there's a deprecation warning message indicating that Connection { onReady: code } should be written as Connections { function onReady() { code } }. I don't know if this works in earlier versions.


Log in to reply