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. Connect to the signal from an object created by stackview.push in QML
Forum Updated to NodeBB v4.3 + New Features

Connect to the signal from an object created by stackview.push in QML

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
17 Posts 2 Posters 2.6k Views 3 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.
  • J James A

    Hai @jeremy_k

    I declared the "item" as local variable as shown below, now the error does not appear , but the "mouse_chg_control.onClicked" slot in BatteryInfo.qml file is not called on emitting the "chrgCntrlClicked" in ChargerInfo.qml file.

    Added the updated code below

    "BatteryInfo.qml" 
    
    Rectangle {
    
        Button {
            id: mouse_batInfo
            x: 207
            y: 176
            text: qsTr("Load")
            onClicked: {
                var item = stackView.push("qrc:/ChargerInfo.qml")
                item.chrgCntrlClicked.connect(mouse_chg_control.onClicked)
            }
        }
    
        Button {
            id: mouse_chg_control
            x: 216
            y: 277
            text: qsTr("Button")
    
            onClicked: {
                console.log("Button clicked")
            }
        }
    
    }
    
    "ChargerInfo.qml"
    
    Rectangle{
    
        id: root
        signal chrgCntrlClicked
    
        Button {
            id: button
            x: 112
            y: 129
            text: qsTr("Button")
            onClicked: {
                root.chrgCntrlClicked
            }
        }
    
    
    }
    
    "main.qml"
    
    ApplicationWindow {
    
        width: 640
    
        height: 480
    
        visible: true
    
        title: qsTr("Hello World")
    
        StackView{
          id : stackView
          initialItem: "qrc:/BatteryInfo.qml"
          anchors.fill: parent
        }
    
    }
    
    jeremy_kJ Offline
    jeremy_kJ Offline
    jeremy_k
    wrote on last edited by
    #7

    @James-A said in Connect to the signal from an object created by stackview.push in QML:

                root.chrgCntrlClicked
    

    This is missing () to invoke the signal.

    As a matter of personal taste, I prefer using Connections over imperative javascript to manage connection to a fixed number of dynamically created objects. Both versions of StackView have a currentItem that points to the top of the stack.

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

    1 Reply Last reply
    1
    • J Offline
      J Offline
      James A
      wrote on last edited by
      #8

      Hi @jeremy_k ,

      Sorry for the delayed reply , the root.chrgCntrlClicked() code helped me to fix the issue. Now I am trying with Repeaters as shown in the below code.

      // BatteryInfo qml file

      RowLayout {
                  anchors.fill: parent
                  Repeater{
                      id: repeater
                      model : [ batteryInfo.bat1 , batteryInfo.bat2 , batteryInfo.bat3 ]
      
                      Battery {
      
                          Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
      
                          mouse_batInfo.onClicked: {
                              var item = stackView.push("ChargeInfo.qml")
      			item.chrgCntrlClicked.connect(mouse_chg_control.onClicked)
                          }
      
                          mouse_chg_control.onClicked: {
                             console.log("Button is clicked")                 
                          }
      
      
      
                      }
                  }
              }
      

      // ChargeInfo.qml file

       signal chrgCntrlClicked
       
       Repeater{
      
                  model : [ batteryInfo.bat1 , batteryInfo.bat2 , batteryInfo.bat3 ]
      
                  // loader is used keep only current item on the screen and load the other UI dynamically on swiping
                  Loader {
                      active: SwipeView.isCurrentItem
                      sourceComponent: Rectangle{
                          ChargeInfoForm {
                              id: chargeInfoForm
      
                              mouse_chg_control.onClicked: {
                                   root.chrgCntrlClicked()
                              }
      
                              txt_batName.text: "Battery " + (index + 1)
      
                          }
                      }
                  }
      
              }
      

      Totally three Items will be created on the UI. Whenever the button is clicked the mouse_chg_control.onClicked function gets called, which has to call the corresponding slot in the Battery info qml file

      But When I click the button in the ChargeInfo.qml file I get error "Error: Insufficient arguments".
      What is proper way to connect the ChargeInfo.qml signal to corresponding BatteryInfo.qml slots ?

      jeremy_kJ 1 Reply Last reply
      0
      • J James A

        Hi @jeremy_k ,

        Sorry for the delayed reply , the root.chrgCntrlClicked() code helped me to fix the issue. Now I am trying with Repeaters as shown in the below code.

        // BatteryInfo qml file

        RowLayout {
                    anchors.fill: parent
                    Repeater{
                        id: repeater
                        model : [ batteryInfo.bat1 , batteryInfo.bat2 , batteryInfo.bat3 ]
        
                        Battery {
        
                            Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
        
                            mouse_batInfo.onClicked: {
                                var item = stackView.push("ChargeInfo.qml")
        			item.chrgCntrlClicked.connect(mouse_chg_control.onClicked)
                            }
        
                            mouse_chg_control.onClicked: {
                               console.log("Button is clicked")                 
                            }
        
        
        
                        }
                    }
                }
        

        // ChargeInfo.qml file

         signal chrgCntrlClicked
         
         Repeater{
        
                    model : [ batteryInfo.bat1 , batteryInfo.bat2 , batteryInfo.bat3 ]
        
                    // loader is used keep only current item on the screen and load the other UI dynamically on swiping
                    Loader {
                        active: SwipeView.isCurrentItem
                        sourceComponent: Rectangle{
                            ChargeInfoForm {
                                id: chargeInfoForm
        
                                mouse_chg_control.onClicked: {
                                     root.chrgCntrlClicked()
                                }
        
                                txt_batName.text: "Battery " + (index + 1)
        
                            }
                        }
                    }
        
                }
        

        Totally three Items will be created on the UI. Whenever the button is clicked the mouse_chg_control.onClicked function gets called, which has to call the corresponding slot in the Battery info qml file

        But When I click the button in the ChargeInfo.qml file I get error "Error: Insufficient arguments".
        What is proper way to connect the ChargeInfo.qml signal to corresponding BatteryInfo.qml slots ?

        jeremy_kJ Offline
        jeremy_kJ Offline
        jeremy_k
        wrote on last edited by
        #9

        @James-A Can you convert the code into a self-contained minimal example? Its easier to spot and fix errors if the code is otherwise executable.

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

        1 Reply Last reply
        0
        • J Offline
          J Offline
          James A
          wrote on last edited by
          #10

          Hi @jeremy_k ,

          I was able to fix the "Error: Insufficient arguments". error. Now I need some idea on how to connect the signal from an Item in the child to parent item

          The BatteryInfo.qml (parent) and ChargerInfo.qml (child) contains 3 items. In child page whenever a button is clicked under an item the corresponding parent item button needs to be called. This is happening with the present code added below.
          But the problem is when I swipe and click the Items button in the child page the corresponding parent item button is not called

          Please execute this code to see the behaviour

          // main.qml

          import QtQuick 2.4
          import QtQuick.Window 2.4
          import QtQuick.Controls 1.4
          
          ApplicationWindow {
          
              width: 700
          
              height: 480
          
              visible: true
          
              title: qsTr("Hello World")
          
              StackView{
                id : stackView
                initialItem: "qrc:/BatteryInfo.qml"
                anchors.fill: parent
              }
          
          }
          

          //Charge.qml

          import QtQuick 2.4
          import QtQuick.Controls 2.3
          
          Rectangle{
          
              id: root
              width: 235
              height: 370
          
              property alias mouse_chg_control: mouse_chg_control
              property alias text1: text1
          
              Button {
                  id: mouse_chg_control
                  x: 87
                  y: 216
                  text: qsTr("Button")
          
              }
          
              Text {
                  id: text1
                  x: 118
                  y: 116
                  text: qsTr("Text")
                  font.pixelSize: 12
              }
          
          
          }
          

          // Battery.qml

          import QtQuick 2.2
          import QtQuick.Shapes 1.2
          import QtQuick.Controls 2.2
          import QtQuick.Layouts 1.0
          
          Rectangle {
              width: 235
              height: 370
              property alias txt_name: txt_name
              property alias mouse_batInfo: mouse_batInfo
              property alias mouse_chg_control: mouse_chg_control
          
              MouseArea {
                  id: mouse_batInfo
                  anchors.fill: parent
              }
          
              Button {
                  id: mouse_chg_control
                  x: 59
                  y: 228
                  width: 100
                  height: 37
                  text: qsTr("Button")
              }
          
              Text {
                  id: txt_name
                  x: 97
                  y: 121
                  text: qsTr("Text")
                  font.pixelSize: 12
              }
          }
          

          //BatteryInfo.qml

          import QtQuick 2.4
          import QtQuick.Controls 2.3
          import QtQuick.Layouts 1.2
          
          Item {
          
              RowLayout {
                  anchors.fill: parent
                  Repeater{
                      id: repeater
                      model : 3
          
                      Battery {
          
                          Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
          
                          txt_name.text: index
          
                          mouse_batInfo.onClicked: {
                              var item = stackView.push("qrc:/ChargeInfo.qml" ,{currentIndex : index})
                              item.chrgCntrlClicked.connect(mouse_chg_control.onClicked)
                          }
          
                          mouse_chg_control.onClicked: {
                              console.log("button clicked : " + index )
                          }
          
                      }
                  }
              }
          
          }
          
          

          // ChargeInfo.qml

          import QtQuick 2.4
          import QtQuick.Controls 2.3
          import QtQuick.Layouts 1.2
          
          Item {
          
              id : chargeinfo
              property alias currentIndex : swipeView.currentIndex
          
              PageIndicator {
                  id: indicator
                  x: 485
                  y: 453
                  width: 50
                  z: 1
                  anchors.horizontalCenterOffset: 8
                  anchors.horizontalCenter: swipeView.horizontalCenter
                  currentIndex: swipeView.currentIndex
                  count: swipeView.count
              }
          
              signal chrgCntrlClicked
          
              SwipeView{
                  id: swipeView
                  width: 650
          
                  anchors.left: parent.left
                  anchors.top: parent.top
                  anchors.bottom: parent.bottom
                  anchors.horizontalCenterOffset: 0
                  anchors.leftMargin: 0
                  anchors.horizontalCenter: parent.horizontalCenter
                  anchors.bottomMargin: 0
                  anchors.topMargin: 71
          
                  Repeater{
          
                      model : 3
          
                      // loader is used keep only current item on the screen and load the other UI dynamically on swiping
                      Loader {
                          active: SwipeView.isCurrentItem
                          sourceComponent:
                              Rectangle{
                              Charger {
          
                                  width: parent.width
                                  anchors.horizontalCenter: parent.horizontalCenter
          
                                  text1.text: index
          
                                  mouse_chg_control.onClicked: {
                                      chargeinfo.chrgCntrlClicked()
                                  }
          
                              }
                          }
                      }
                  }
              }
          
              Button{
          
                  text: "BACK"
          
                  onClicked: {
          
                      if (stackView.depth > 1) {
                          stackView.pop()
                      }
          
                  }
              }
          
          }
          
          
          1 Reply Last reply
          0
          • jeremy_kJ Offline
            jeremy_kJ Offline
            jeremy_k
            wrote on last edited by jeremy_k
            #11

            Lets start from a simpler example:

            main.qml:

            import QtQuick 2.4
            import QtQuick.Controls 1.4
            
            ApplicationWindow {
                width: 700
                height: 480
                visible: true
            
                StackView{
                  id : stackView
                  initialItem: A{}
                  anchors.fill: parent
                }
            
                Connections {
                    target: stackView.currentItem
                    function onClicked() { console.log("got a click"); }
                }
            }
            

            A.qml:

            import QtQuick 2.2
            import QtQuick.Controls 2.2
            
            Rectangle {
                id: root
                signal clicked()
                Button {
                    anchors.centerIn: parent
                    text: "button"
                    onClicked: root.clicked()
                }
            }
            

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

            1 Reply Last reply
            1
            • J Offline
              J Offline
              James A
              wrote on last edited by
              #12

              Hai @jeremy_k ,

              Using target: stackView.currentItem was a good idea. I tried running , its working fine.
              But if there are A , B , C (child) qml files. and three onClicked slots for each child in main qml file , how to connect corresponding signals from child to main qml file

              child.qml || main.qml

              A.qml --> onAClicked()
              B.qml --> onBClicked()
              C.qml --> onCClicked()

              jeremy_kJ 1 Reply Last reply
              0
              • J James A

                Hai @jeremy_k ,

                Using target: stackView.currentItem was a good idea. I tried running , its working fine.
                But if there are A , B , C (child) qml files. and three onClicked slots for each child in main qml file , how to connect corresponding signals from child to main qml file

                child.qml || main.qml

                A.qml --> onAClicked()
                B.qml --> onBClicked()
                C.qml --> onCClicked()

                jeremy_kJ Offline
                jeremy_kJ Offline
                jeremy_k
                wrote on last edited by
                #13

                @James-A said in Connect to the signal from an object created by stackview.push in QML:

                But if there are A , B , C (child) qml files. and three onClicked slots for each child in main qml file , how to connect corresponding signals from child to main qml file

                Do you expect to interact with all three at the same time, or only the item currently at the top of the stack?

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

                1 Reply Last reply
                0
                • J Offline
                  J Offline
                  James A
                  wrote on last edited by
                  #14

                  @jeremy_k

                  Only with one item which is currently at the top of the stack

                  jeremy_kJ 1 Reply Last reply
                  0
                  • J James A

                    @jeremy_k

                    Only with one item which is currently at the top of the stack

                    jeremy_kJ Offline
                    jeremy_kJ Offline
                    jeremy_k
                    wrote on last edited by
                    #15

                    @James-A said in Connect to the signal from an object created by stackview.push in QML:

                    @jeremy_k

                    Only with one item which is currently at the top of the stack

                    Then there's no need to deal each item individually. As long as all three use signals with the same name, Connections { target: stackView.currentItem } will rebind to the new currentItem, and make the connection.

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

                    1 Reply Last reply
                    1
                    • J Offline
                      J Offline
                      James A
                      wrote on last edited by
                      #16

                      @jeremy_k

                      I updated the BatteryInfo.qml class as shown below

                      import QtQuick 2.4
                      import QtQuick.Controls 2.3
                      import QtQuick.Layouts 1.2
                      
                      Item {
                      
                          Connections {
                              target: stackView.currentItem
                              function onChrgCntrlClicked()
                              { console.log("got a click");
                                battery.mouse_chg_control.clicked()
                              }
                          }
                      
                          RowLayout {
                              anchors.fill: parent
                              Repeater{
                                  id: repeater
                                  model : 3
                      
                                  Battery {
                                      id : battery
                                      Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
                      
                                      txt_name.text: index
                      
                                      mouse_batInfo.onClicked: {
                                          stackView.push("qrc:/ChargeInfo.qml" ,{currentIndex : index})
                                      }
                      
                                      mouse_chg_control.onClicked: {
                                          console.log("button clicked : " + index )
                                      }
                      
                                  }
                              }
                          }
                      
                      }
                      
                      

                      I was getting the below error message

                      qrc:/BatteryInfo.qml:7:5: QML Connections: Detected function "onChrgCntrlClicked" in Connections element. This is probably intended to be a signal handler but no signal of the target matches the name.
                      qml: got a click
                      qrc:/BatteryInfo.qml:11: ReferenceError: battery is not defined

                      jeremy_kJ 1 Reply Last reply
                      0
                      • J James A

                        @jeremy_k

                        I updated the BatteryInfo.qml class as shown below

                        import QtQuick 2.4
                        import QtQuick.Controls 2.3
                        import QtQuick.Layouts 1.2
                        
                        Item {
                        
                            Connections {
                                target: stackView.currentItem
                                function onChrgCntrlClicked()
                                { console.log("got a click");
                                  battery.mouse_chg_control.clicked()
                                }
                            }
                        
                            RowLayout {
                                anchors.fill: parent
                                Repeater{
                                    id: repeater
                                    model : 3
                        
                                    Battery {
                                        id : battery
                                        Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
                        
                                        txt_name.text: index
                        
                                        mouse_batInfo.onClicked: {
                                            stackView.push("qrc:/ChargeInfo.qml" ,{currentIndex : index})
                                        }
                        
                                        mouse_chg_control.onClicked: {
                                            console.log("button clicked : " + index )
                                        }
                        
                                    }
                                }
                            }
                        
                        }
                        
                        

                        I was getting the below error message

                        qrc:/BatteryInfo.qml:7:5: QML Connections: Detected function "onChrgCntrlClicked" in Connections element. This is probably intended to be a signal handler but no signal of the target matches the name.
                        qml: got a click
                        qrc:/BatteryInfo.qml:11: ReferenceError: battery is not defined

                        jeremy_kJ Offline
                        jeremy_kJ Offline
                        jeremy_k
                        wrote on last edited by
                        #17

                        @James-A said in Connect to the signal from an object created by stackview.push in QML:

                        @jeremy_k

                        I updated the BatteryInfo.qml class as shown below
                        [...]

                        There is nothing with the id stackView here. It's too confusing for me to attempt to stitch together code from previous posts and infer missing portions. Please use examples that are both simple and complete. Remove everything that is not related to the problem at hand, and include everything that a reader would need to copy and paste to achieve the same result.

                        I was getting the below error message

                        qrc:/BatteryInfo.qml:7:5: QML Connections: Detected function "onChrgCntrlClicked" in Connections element. This is probably intended to be a signal handler but no signal of the target matches the name.
                        qml: got a click
                        qrc:/BatteryInfo.qml:11: ReferenceError: battery is not defined

                        These are both generally straight forward errors. Is there a chrgCntrlClicked signal associated with stackView.currentItem? Is it a signal of a child item that needs to be propagated, or is there a typo? Setting the ignoreUnknownSignals property to allow for transitory states that lack the signal can help to silence irrelevant warnings.

                        Is there a battery property or variable in scope? Ids in a Repeater or ListView delegate are not meaningful outside of a delegate instance. The example above has 3 instances of Battery called battery created in a Repeater. Which one is battery supposed to reference?

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

                        1 Reply Last reply
                        1

                        • Login

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