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. Problem with signal and Dynamic Object created
Forum Updated to NodeBB v4.3 + New Features

Problem with signal and Dynamic Object created

Scheduled Pinned Locked Moved Solved QML and Qt Quick
7 Posts 3 Posters 2.4k 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.
  • A Offline
    A Offline
    AboutClod
    wrote on 15 May 2018, 15:48 last edited by AboutClod
    #1

    Hello everyone, i'm new in QtQuick and i'm trying to develop an desktop app.
    I've created my custom object, called "TabTPDef". It has a SwipeView with "TapTPMonitor" and "TabTPPrint".
    This object have been dynamically added with the code

     var component;
                           var tab;
                           component = Qt.createComponent("TabTPDef.qml");
        if( component.status != Component.Ready )
        {
            if( component.status == Component.Error )
                console.debug("Error:"+ component.errorString() );
            return;
        }
                           tab= component.createObject(dhsbLink, {objectName:"tp2","buttonId":"i"+2,"monitorId":"m"+2});
    
    

    where "dhsbLink" is the parent, and objectName and buttonId helps me to identify which of these tab is "talking". I have 4 of this TabTPDef dynamically created in dhsbLink.

    I have a slot and a signal to update the monitor. I can update the monitor well, searching the children of dhsbLink and compare the objectName. So if Monitor of TP2 is clicked, the monitor updated is ONLY the TP2. When I dynamically create one "TabTPDef", it fills the monitor well. When i create two of these, the app see two object created and emit the signal twice. If three of TabTPDef are create it emit signal for three times.
    Screen to explain:
    0_1526398974100_easyfull.png
    0_1526398982584_easyfull2.png

    I'm trying to achieve the Qt::DirectConnection, but i don't know if this is the solution.

    Maybe i've explained bad, my English is not so well, so if you don't understand ask me to be more accurate.

    Sorry..

    Thank You!!!!

    J 1 Reply Last reply 16 May 2018, 08:48
    0
    • A AboutClod
      15 May 2018, 15:48

      Hello everyone, i'm new in QtQuick and i'm trying to develop an desktop app.
      I've created my custom object, called "TabTPDef". It has a SwipeView with "TapTPMonitor" and "TabTPPrint".
      This object have been dynamically added with the code

       var component;
                             var tab;
                             component = Qt.createComponent("TabTPDef.qml");
          if( component.status != Component.Ready )
          {
              if( component.status == Component.Error )
                  console.debug("Error:"+ component.errorString() );
              return;
          }
                             tab= component.createObject(dhsbLink, {objectName:"tp2","buttonId":"i"+2,"monitorId":"m"+2});
      
      

      where "dhsbLink" is the parent, and objectName and buttonId helps me to identify which of these tab is "talking". I have 4 of this TabTPDef dynamically created in dhsbLink.

      I have a slot and a signal to update the monitor. I can update the monitor well, searching the children of dhsbLink and compare the objectName. So if Monitor of TP2 is clicked, the monitor updated is ONLY the TP2. When I dynamically create one "TabTPDef", it fills the monitor well. When i create two of these, the app see two object created and emit the signal twice. If three of TabTPDef are create it emit signal for three times.
      Screen to explain:
      0_1526398974100_easyfull.png
      0_1526398982584_easyfull2.png

      I'm trying to achieve the Qt::DirectConnection, but i don't know if this is the solution.

      Maybe i've explained bad, my English is not so well, so if you don't understand ask me to be more accurate.

      Sorry..

      Thank You!!!!

      J Offline
      J Offline
      JKSH
      Moderators
      wrote on 16 May 2018, 08:48 last edited by
      #2

      Hi @AboutClod , what is the issue that you have?

      Does this help? See "Connecting Signals to Methods and Signals" at http://doc.qt.io/qt-5/qtqml-syntax-signals.html#connecting-signals-to-methods-and-signals

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      1 Reply Last reply
      1
      • A Offline
        A Offline
        AboutClod
        wrote on 16 May 2018, 10:02 last edited by AboutClod
        #3

        Hi JKSH, i need to be more accurate.

        I've created "TP2" and "TP3" with the statements

        buttTp2.mouseButton.onClicked: {
            var component;
                               var tp2;
                               component = Qt.createComponent("TabTPDef.qml");
            if( component.status != Component.Ready )
            {
                if( component.status == Component.Error )
                    console.debug("Error:"+ component.errorString() );
                return;
            }
                               tp2 = component.createObject(dhsbLink{objectName:"tp2","buttonId":"i"+2,"monitorId":"m"+2});
            tp2.anchors.top = dhsbLink.top
            tp2.anchors.topMargin = 100
            tp2.anchors.left = dhsbLink.left
            tp2.anchors.leftMargin = 300
            tp2.anchors.bottom = dhsbLink.bottom
            tp2.frateto.txtButt.text = "TP2";
            tp2.frateto.buttonMain.state = "off"
             tp2.frateto.clicked.connect(buttonClicked);
        }
        
        
        
        
        
        buttTp3.mouseButton.onClicked: {
            var component;
                               var tp3;
                               component = Qt.createComponent("TabTPDef.qml");
                                tp3 = component.createObject(dhsbLink, {objectName:"tp3","buttonId":"i"+3,"monitorId":"m"+3});
        
        
            tp3.anchors.top = dhsbLink.top
            tp3.anchors.topMargin = 100
            tp3.anchors.left = dhsbLink.left
            tp3.anchors.leftMargin = 600
            tp3.anchors.bottom = dhsbLink.bottom
            tp3.frateto.txtButt.text = "TP3";
            tp3.frateto.buttonMain.state = "off"
           tp3.frateto.clicked.connect(buttonClicked);
        
        
        
        }
        

        I connect the clicked signal emitted by TabTPDef here:

        Item {
            id: tabTPDEF
            height: 700
            width: 325
            objectName: "test_rect"
          ...
            SwipeView {
                id: swipe
               currentIndex: 0
               clip: true
                anchors.fill: parent
        
                TabTPMonitor{
                id: frateto
                buttonMain.onClicked: {
                    clicked(tabTPDEF.buttonId,tabTPDEF.monitorId)
                  }
                }
                TabTP{
                 id: viewer
                }
            }
        

        with the function buttonClicked descripted here:

        function buttonClicked(buttonId,monitorId)
           {
        
            for(var i = 0; i <dhsbLink.children.length; i++)
                       {
        
                           if(dhsbLink.children[i].buttonId == buttonId)
                           {
                              if(dhsbLink.children[i].frateto.buttonMain.state=="off"){
                                  dhsbLink.children[i].frateto.buttonMain.state="on"
                               easy.open(dhsbLink.children[i].frateto.txtButt.text,i,monitorId)
                              } else {
                                 dhsbLink.children[i].frateto.buttonMain.state="off";
                              }
                           }
                           else
                           {
        
                           }
           }
        
        }
        

        where "easy.open(dhsbLink.children[i].frateto.txtButt.text,i,monitorId)" is a c++ method that update the monitor in the screen of the first post, with slot and signal. On Signal Monitor emitted, the text passed by C++ is catch in QML here:

         onSegnaleMonitor: {
         if(dhsbLink.children[children].objectName == trgt ){  
        //trgt is the object name of the "TP" returned by C++
            dhsbLink.children[children].frateto.textArea.text = dhsbLink.children[children].frateto.textArea.text+text+"\n"
                              }      
                    }
        }
        

        When I check "onSegnaleMonitor" in the debugger, it made the operation

        dhsbLink.children[children].frateto.textArea.text = dhsbLink.children[children].frateto.textArea.text+text+"\n"
        

        twice if the "TabTPDef" created are two, three times if the "TabTPDef" created are three etc. as seen in the screen of the first post. He recognize who call the "clicked" signal with "dhsbLink.children[children]" and fill the right "TabTPDef", but the signal see two equal object created, and even if the slot is started once, the signal emit twice.

        Thank you!
        and thank you for your patience!

        1 Reply Last reply
        0
        • dheerendraD Offline
          dheerendraD Offline
          dheerendra
          Qt Champions 2022
          wrote on 16 May 2018, 10:28 last edited by
          #4

          I read the post and tried to understand what is the issue. It is not very clear to me. Still trying to answer based on what I have understood. If three objects are created, it will make three connects, and it has to emit three signals and hence 3 times slot should be called.

          Your example is big. Can you create simple example and explain the issue ?

          Dheerendra
          @Community Service
          Certified Qt Specialist
          http://www.pthinks.com

          J 1 Reply Last reply 16 May 2018, 14:03
          2
          • dheerendraD dheerendra
            16 May 2018, 10:28

            I read the post and tried to understand what is the issue. It is not very clear to me. Still trying to answer based on what I have understood. If three objects are created, it will make three connects, and it has to emit three signals and hence 3 times slot should be called.

            Your example is big. Can you create simple example and explain the issue ?

            J Offline
            J Offline
            JKSH
            Moderators
            wrote on 16 May 2018, 14:03 last edited by
            #5

            @dheerendra said in Problem with signal and Dynamic Object created:

            Your example is big. Can you create simple example and explain the issue ?

            I agree with @dheerendra. Please make a smaller example that is easier to understand.

            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

            1 Reply Last reply
            1
            • A Offline
              A Offline
              AboutClod
              wrote on 16 May 2018, 16:01 last edited by
              #6

              Ok guys, i made the example, and found a solution.

              This is my project directory:
              0_1526484752385_1.png

              In main, i define a Item "DhsbLink" as parent and a "Page1a".

              //main.qml
              import QtQuick 2.9
              import QtQuick.Controls 2.2
              
              ApplicationWindow {
                  visible: true
                  width: 900
                  height: 700
                  property alias dhsbLink : dhsbLink
                  title: qsTr("Tabs")
              
                  Item{
                      id: dhsbLink
                      anchors.fill:parent
              
              
                      Page1a {
                          id: subtab
                      }
              
              
                  
              
              
              
                  Connections{
                      id: link
                      target: easyFull
                      ignoreUnknownSignals: true
                      onSomeSignal: {
              
              
                        if(dhsbLink.children[children].monitorId == mId){
                          dhsbLink.children[children].txtArea.text =  dhsbLink.children[children].txtArea.text + text + "\n"
                             }
              
                          }
                      }
                  
                  
                  
                  }
              }
              
              

              In "MonitorForm" i create a little monitor, as seen in the original project

              //MonitorForm.ui.qml
              import QtQuick 2.9
              import QtQuick.Controls 2.2
              
              Item {
                  id: monitorTab
                  width: 400
                  height: 400
                  property alias monitorTab: monitorTab
                  property alias txtArea: txtArea
                  property alias starter: starter
                  property string monitorId: monitorId
                  signal clicked(string mId)
                  TextArea {
                      id: txtArea
                      height: 200
                      width: 300
                      background: Rectangle {
                          anchors.fill: parent
                          color: "grey"
                      }
              
                      Button {
                          id: starter
                          text: "starter"
                          width: 50
                          height: 50
                      }
                  }
              }
              
              

              where I call the signal "clicked" on the button clicked with:

              starter.onClicked: {
              
                      clicked(monitorTab.monitorId)
              
              }
              

              Finally In "Page1a" i created a simple button

              ...
                      Button {
                          id: button
                          x: 469
                          y: 30
                          text: qsTr("Button")
                      }
                  }
              

              and at onClick and onPressAndHold it creates "Monitor.qml" objects with:

               button.onClicked: {
                      var component;
                  var sprite;
                  component = Qt.createComponent("Monitor.qml");
                  sprite = component.createObject(dhsbLink, {objectName:"tp2","monitorId":"m"+1});
              
                  sprite.clicked.connect(buttonClicked);
                  }
              
                  
              
                  button.onPressAndHold: {
                      var component;
                  var sprite;
                  component = Qt.createComponent("Monitor.qml");
              
                  sprite = component.createObject(dhsbLink, {objectName:"tp3","monitorId":"m"+2, x:400});
                      sprite.clicked.connect(buttonClicked);
                  }
              

              where i connect the clicked signal with the function buttonClicked descripted in "Page1a"

              function buttonClicked(monitorId) {
                      
                      for(var i=0;i<dhsbLink.children.length;i++){
                      if(dhsbLink.children[i].monitorId == monitorId){
                            easyFull.apreDispositivo(i,monitorId)
                      }
                  }
              }
              

              The C++ method "apreDispositivo" receives the index of children and the monitorId and call some slots passing the index of the children, some string, and the monitor id

              void easyFull::apreDispositivo(QString children,QString mId)
              {
                  int intCont = 1;
                  int intResult = 0;
                 QString strResult;
                   someSlot(children,"LinkConnecting",mId);
                 someSlot(children,"LinkConnecting riuscita",mId);
                  //txtMonitor.text = "LinkConnecting riuscita";
                  intCont = 1;
                  someSlot(children,"LinkConnected",mId);
              ...
              

              then the Connection descripted in main.qml :

              Connections{
                      id: link
                      target: easyFull
                      ignoreUnknownSignals: true
                      onSomeSignal: {
              
              
                        if(dhsbLink.children[children].monitorId == mId){
                          dhsbLink.children[children].txtArea.text =  dhsbLink.children[children].txtArea.text + text + "\n"
                             }
              
                          }
                      }
              

              where "children" is the index of the children passed by C++.

              Result? It works as i want.
              0_1526485687753_2.png
              0_1526485695064_3.png

              So I was searching in my code what could was wrong and I have my Connections {} statement in the "TabTPDef", while in the exampleqt my Connections {} statement was in the main, in the parent where i've created the dynamic object. It was completely wrong. So I moved it in the dhsbLink Tab, and it works as expected!

              0_1526486060672_4.png

              No one string is equal to the previous one, as i want!
              As you can see, the signal for the below text in the pic, is still in the TabTPDef, and it write "1" as many as the created objects.

              The question can be marked as solved.

              I apologize for my previous bad explanation. My english have to be improved. I apologize if I made you waste your time.

              Thank you for your time and your patience, @dheerendra and @JKSH !!!

              J 1 Reply Last reply 17 May 2018, 02:25
              0
              • A AboutClod
                16 May 2018, 16:01

                Ok guys, i made the example, and found a solution.

                This is my project directory:
                0_1526484752385_1.png

                In main, i define a Item "DhsbLink" as parent and a "Page1a".

                //main.qml
                import QtQuick 2.9
                import QtQuick.Controls 2.2
                
                ApplicationWindow {
                    visible: true
                    width: 900
                    height: 700
                    property alias dhsbLink : dhsbLink
                    title: qsTr("Tabs")
                
                    Item{
                        id: dhsbLink
                        anchors.fill:parent
                
                
                        Page1a {
                            id: subtab
                        }
                
                
                    
                
                
                
                    Connections{
                        id: link
                        target: easyFull
                        ignoreUnknownSignals: true
                        onSomeSignal: {
                
                
                          if(dhsbLink.children[children].monitorId == mId){
                            dhsbLink.children[children].txtArea.text =  dhsbLink.children[children].txtArea.text + text + "\n"
                               }
                
                            }
                        }
                    
                    
                    
                    }
                }
                
                

                In "MonitorForm" i create a little monitor, as seen in the original project

                //MonitorForm.ui.qml
                import QtQuick 2.9
                import QtQuick.Controls 2.2
                
                Item {
                    id: monitorTab
                    width: 400
                    height: 400
                    property alias monitorTab: monitorTab
                    property alias txtArea: txtArea
                    property alias starter: starter
                    property string monitorId: monitorId
                    signal clicked(string mId)
                    TextArea {
                        id: txtArea
                        height: 200
                        width: 300
                        background: Rectangle {
                            anchors.fill: parent
                            color: "grey"
                        }
                
                        Button {
                            id: starter
                            text: "starter"
                            width: 50
                            height: 50
                        }
                    }
                }
                
                

                where I call the signal "clicked" on the button clicked with:

                starter.onClicked: {
                
                        clicked(monitorTab.monitorId)
                
                }
                

                Finally In "Page1a" i created a simple button

                ...
                        Button {
                            id: button
                            x: 469
                            y: 30
                            text: qsTr("Button")
                        }
                    }
                

                and at onClick and onPressAndHold it creates "Monitor.qml" objects with:

                 button.onClicked: {
                        var component;
                    var sprite;
                    component = Qt.createComponent("Monitor.qml");
                    sprite = component.createObject(dhsbLink, {objectName:"tp2","monitorId":"m"+1});
                
                    sprite.clicked.connect(buttonClicked);
                    }
                
                    
                
                    button.onPressAndHold: {
                        var component;
                    var sprite;
                    component = Qt.createComponent("Monitor.qml");
                
                    sprite = component.createObject(dhsbLink, {objectName:"tp3","monitorId":"m"+2, x:400});
                        sprite.clicked.connect(buttonClicked);
                    }
                

                where i connect the clicked signal with the function buttonClicked descripted in "Page1a"

                function buttonClicked(monitorId) {
                        
                        for(var i=0;i<dhsbLink.children.length;i++){
                        if(dhsbLink.children[i].monitorId == monitorId){
                              easyFull.apreDispositivo(i,monitorId)
                        }
                    }
                }
                

                The C++ method "apreDispositivo" receives the index of children and the monitorId and call some slots passing the index of the children, some string, and the monitor id

                void easyFull::apreDispositivo(QString children,QString mId)
                {
                    int intCont = 1;
                    int intResult = 0;
                   QString strResult;
                     someSlot(children,"LinkConnecting",mId);
                   someSlot(children,"LinkConnecting riuscita",mId);
                    //txtMonitor.text = "LinkConnecting riuscita";
                    intCont = 1;
                    someSlot(children,"LinkConnected",mId);
                ...
                

                then the Connection descripted in main.qml :

                Connections{
                        id: link
                        target: easyFull
                        ignoreUnknownSignals: true
                        onSomeSignal: {
                
                
                          if(dhsbLink.children[children].monitorId == mId){
                            dhsbLink.children[children].txtArea.text =  dhsbLink.children[children].txtArea.text + text + "\n"
                               }
                
                            }
                        }
                

                where "children" is the index of the children passed by C++.

                Result? It works as i want.
                0_1526485687753_2.png
                0_1526485695064_3.png

                So I was searching in my code what could was wrong and I have my Connections {} statement in the "TabTPDef", while in the exampleqt my Connections {} statement was in the main, in the parent where i've created the dynamic object. It was completely wrong. So I moved it in the dhsbLink Tab, and it works as expected!

                0_1526486060672_4.png

                No one string is equal to the previous one, as i want!
                As you can see, the signal for the below text in the pic, is still in the TabTPDef, and it write "1" as many as the created objects.

                The question can be marked as solved.

                I apologize for my previous bad explanation. My english have to be improved. I apologize if I made you waste your time.

                Thank you for your time and your patience, @dheerendra and @JKSH !!!

                J Offline
                J Offline
                JKSH
                Moderators
                wrote on 17 May 2018, 02:25 last edited by JKSH
                #7

                Hi @AboutClod, I'm glad you found a solution.

                Your English is fine and you didn't waste our time. Please don't worry :)

                However, I'd like to suggest some improvements: Your example should be simpler, shorter, and less complex. You code formatting should also be cleaner. If you do this, your examples will be much easier to understand so people can better help you.

                Here is an example of bad formatting:

                button.onClicked: {
                       var component;
                   var sprite;
                   component = Qt.createComponent("Monitor.qml");
                   sprite = component.createObject(dhsbLink, {objectName:"tp2","monitorId":"m"+1});
                
                   sprite.clicked.connect(buttonClicked);
                   }
                

                This is how it should be formatted:

                button.onClicked: {
                    var component;
                    var sprite;
                    component = Qt.createComponent("Monitor.qml");
                    sprite = component.createObject(dhsbLink, {objectName:"tp2","monitorId":"m"+1});
                
                    sprite.clicked.connect(buttonClicked);
                }
                

                Furthermore, you can shorted your code like this:

                button.onClicked: {
                    var component = Qt.createComponent("Monitor.qml");
                    var sprite = component.createObject(dhsbLink, {objectName:"tp2","monitorId":"m"+1});
                    sprite.clicked.connect(buttonClicked);
                }
                

                @AboutClod said in Problem with signal and Dynamic Object created:

                The question can be marked as solved.

                Please do this: Click "Topic Tools" -> "Mark as Solved"

                Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                1 Reply Last reply
                3

                1/7

                15 May 2018, 15:48

                • Login

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