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. How to add Items dynamically to a Row? (in javascript)
Forum Updated to NodeBB v4.3 + New Features

How to add Items dynamically to a Row? (in javascript)

Scheduled Pinned Locked Moved Solved QML and Qt Quick
13 Posts 4 Posters 2.1k 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.
  • mbruelM Offline
    mbruelM Offline
    mbruel
    wrote on last edited by
    #3

    hum I see, so I've updated my code to be:

            function addItem(idName, imagePath){
                console.log("adding item: " + idName);
                var c = Qt.createComponent("ToolBarButton.qml");
                var button = c.createObject(toolBar, {
                                                        id: idName,
                                                        imagePath: imagePath,
                                                        height: toolBar.height,
                                                        width: 50,
                                                        state: "Inactive",
                                                        barIndex: toolBar.children.length
                                                    });
            }
    
            Component.onCompleted: {
                addItem("profile", "img/profile.png");
            }
    
            Connections{
                target: profile
                onSelected: changeMainMenu(idx);
            }
    

    I'm getting now getting the issue: qrc:/main.qml:186: ReferenceError: profile is not defined

    So if I understand well I can't set the id of an object created dynamically? Is that right?
    This wouldn't be such a big deal but then how can I connect a signal of that object created dynamically?

    ODБOïO 1 Reply Last reply
    0
    • mbruelM mbruel

      hum I see, so I've updated my code to be:

              function addItem(idName, imagePath){
                  console.log("adding item: " + idName);
                  var c = Qt.createComponent("ToolBarButton.qml");
                  var button = c.createObject(toolBar, {
                                                          id: idName,
                                                          imagePath: imagePath,
                                                          height: toolBar.height,
                                                          width: 50,
                                                          state: "Inactive",
                                                          barIndex: toolBar.children.length
                                                      });
              }
      
              Component.onCompleted: {
                  addItem("profile", "img/profile.png");
              }
      
              Connections{
                  target: profile
                  onSelected: changeMainMenu(idx);
              }
      

      I'm getting now getting the issue: qrc:/main.qml:186: ReferenceError: profile is not defined

      So if I understand well I can't set the id of an object created dynamically? Is that right?
      This wouldn't be such a big deal but then how can I connect a signal of that object created dynamically?

      ODБOïO Offline
      ODБOïO Offline
      ODБOï
      wrote on last edited by
      #4

      @mbruel

      function createButton() {
             var btn = btnComponent.createObject(row,{ text : "myButton"});
             btn.onClicked.connect(btnClicked)
         }
      
         function btnClicked(){console.log("button clicked")}
      
      1 Reply Last reply
      1
      • mbruelM Offline
        mbruelM Offline
        mbruel
        wrote on last edited by
        #5

        great, I got what I wanted with that piece of code:

            Row {
                id: toolBar
                anchors.bottom: parent.bottom
                anchors.bottomMargin: 20;
                anchors.horizontalCenter: parent.horizontalCenter
                spacing: 15
        
                height: 50
        
        
                function addItem(idName){
                    console.log("adding item: " + idName);
                    var c = Qt.createComponent("ToolBarButton.qml");
                    var barIdx = toolBar.children.length;
                    var button = c.createObject(toolBar, {
                                                            id: idName,
                                                            imagePath: "img/"+idName+".png",
                                                            height: toolBar.height,
                                                            width: 50,
                                                            state: barIdx === 0 ? "Selected": "Inactive",
                                                            barIndex: toolBar.children.length
                                                        });
                    button.onSelected.connect(changeMainMenu);
                }
        
        
                Component.onCompleted: {
                    addItem("home");
                    addItem("mail");
                    addItem("compas");
                    addItem("stack");
                    addItem("profile");
                }
            }
        

        my ToolBarButton Item is emitting the "selected" signal.

        Last question that is a bit out of the scope of this thread. How can I create a List of string that I would iterate in my onCompleted method?
        Like a property or simple variable of my root Window.

        ODБOïO 1 Reply Last reply
        0
        • mbruelM mbruel

          great, I got what I wanted with that piece of code:

              Row {
                  id: toolBar
                  anchors.bottom: parent.bottom
                  anchors.bottomMargin: 20;
                  anchors.horizontalCenter: parent.horizontalCenter
                  spacing: 15
          
                  height: 50
          
          
                  function addItem(idName){
                      console.log("adding item: " + idName);
                      var c = Qt.createComponent("ToolBarButton.qml");
                      var barIdx = toolBar.children.length;
                      var button = c.createObject(toolBar, {
                                                              id: idName,
                                                              imagePath: "img/"+idName+".png",
                                                              height: toolBar.height,
                                                              width: 50,
                                                              state: barIdx === 0 ? "Selected": "Inactive",
                                                              barIndex: toolBar.children.length
                                                          });
                      button.onSelected.connect(changeMainMenu);
                  }
          
          
                  Component.onCompleted: {
                      addItem("home");
                      addItem("mail");
                      addItem("compas");
                      addItem("stack");
                      addItem("profile");
                  }
              }
          

          my ToolBarButton Item is emitting the "selected" signal.

          Last question that is a bit out of the scope of this thread. How can I create a List of string that I would iterate in my onCompleted method?
          Like a property or simple variable of my root Window.

          ODБOïO Offline
          ODБOïO Offline
          ODБOï
          wrote on last edited by ODБOï
          #6

          @mbruel said in How to add Items dynamically to a Row? (in javascript):

          Last question that is a bit out of the scope of this thread. How can I create a List of string that I would iterate in my onCompleted method?

          Like a property or simple variable of my root Window.

          https://doc.qt.io/qt-5/qtqml-syntax-objectattributes.html

          property var someList: [ "three", "four"]
          
          1 Reply Last reply
          0
          • mbruelM Offline
            mbruelM Offline
            mbruel
            wrote on last edited by
            #7

            great, @LeLev you rock!

            here is the updated code:

                Row {
                    property var menuList : ["home", "mail", "compas", "stack", "profile"]
                    
                    id: toolBar
                    anchors.bottom: parent.bottom
                    anchors.bottomMargin: 20;
                    anchors.horizontalCenter: parent.horizontalCenter
                    spacing: 15
            
                    height: 50
            
            
                    function addItem(idName){
                        console.log("adding item: " + idName);
                        var c = Qt.createComponent("ToolBarButton.qml");
                        var barIdx = toolBar.children.length;
                        var button = c.createObject(toolBar, {
                                                                id: idName,
                                                                imagePath: "img/"+idName+".png",
                                                                height: toolBar.height,
                                                                width: 50,
                                                                state: barIdx === 0 ? "Selected": "Inactive",
                                                                barIndex: toolBar.children.length
                                                            });
                        button.onSelected.connect(changeMainMenu);
                    }
            
                    Component.onCompleted: {
                        for (var i=0; i < menuList.length; ++i)
                            addItem(menuList[i]);
                    }
                }
            
            1 Reply Last reply
            0
            • fcarneyF Offline
              fcarneyF Offline
              fcarney
              wrote on last edited by
              #8

              Here is another way to add unique items using a repeater and a loader (see last post):
              https://forum.qt.io/topic/117076/random-customs-controls-in-a-row/3

              C++ is a perfectly valid school of magic.

              mbruelM 1 Reply Last reply
              1
              • fcarneyF fcarney

                Here is another way to add unique items using a repeater and a loader (see last post):
                https://forum.qt.io/topic/117076/random-customs-controls-in-a-row/3

                mbruelM Offline
                mbruelM Offline
                mbruel
                wrote on last edited by
                #9

                @fcarney
                sounds less intuitive but I'll have a look, thanks ;)

                1 Reply Last reply
                0
                • GrecKoG Offline
                  GrecKoG Offline
                  GrecKo
                  Qt Champions 2018
                  wrote on last edited by
                  #10

                  You should refrain from using Qt.createComponent and manual dynamic instantiation in QML.

                  Stay declarative.

                  Your task can be achieved like so :

                  Row {
                     id: toolBar
                     property var menuList : ["home", "mail", "compas", "stack", "profile"]
                     property int currentIndex: 0
                      
                      anchors {
                          bottom: parent.bottom
                          bottomMargin: 20;
                          horizontalCenter: parent.horizontalCenter
                      }
                      spacing: 15
                      height: 50
                  
                      Repeater {
                          model: toolBar.menuList
                          ToolBarButton {
                              id: button
                              imagePath: "img/" + model.modelData + ".png"
                              height: toolBar.height
                              width: 50
                              barIndex: model.index
                              state:barIndex === toolBar.currentIndex ?  "Selected" : "Inactive"
                              onSelected: toolBar.currentIndex = barIndex
                          }
                      }
                  }
                  

                  I also changed the selected button logic here to be self contained and because I didn't know what were the definition of your selected signal or changeMainMenu function.

                  mbruelM 1 Reply Last reply
                  2
                  • GrecKoG GrecKo

                    You should refrain from using Qt.createComponent and manual dynamic instantiation in QML.

                    Stay declarative.

                    Your task can be achieved like so :

                    Row {
                       id: toolBar
                       property var menuList : ["home", "mail", "compas", "stack", "profile"]
                       property int currentIndex: 0
                        
                        anchors {
                            bottom: parent.bottom
                            bottomMargin: 20;
                            horizontalCenter: parent.horizontalCenter
                        }
                        spacing: 15
                        height: 50
                    
                        Repeater {
                            model: toolBar.menuList
                            ToolBarButton {
                                id: button
                                imagePath: "img/" + model.modelData + ".png"
                                height: toolBar.height
                                width: 50
                                barIndex: model.index
                                state:barIndex === toolBar.currentIndex ?  "Selected" : "Inactive"
                                onSelected: toolBar.currentIndex = barIndex
                            }
                        }
                    }
                    

                    I also changed the selected button logic here to be self contained and because I didn't know what were the definition of your selected signal or changeMainMenu function.

                    mbruelM Offline
                    mbruelM Offline
                    mbruel
                    wrote on last edited by
                    #11

                    @GrecKo
                    Nice, thanks a lot!
                    Indeed it looks much better that way. I've checked the Repeater documentation and it's defo what I should use.
                    Here is the updated code which is nearly exactly what you gave me:

                        Row {
                            id: toolBar
                            anchors {
                                bottom: parent.bottom
                                bottomMargin: toolBarMargin;
                                horizontalCenter: parent.horizontalCenter
                            }
                    
                            height:  toolBarHeight
                            spacing: toolBarSpacing
                    
                            Repeater {
                                model: menuList
                                ToolBarButton {
                                    id: button
                                    imagePath: "img/" + model.modelData + ".png"
                                    height: toolBar.height
                                    width: toolBarButtonWidth
                                    barIndex: model.index
                                    state: model.index === 0 ?  "Selected" : "Inactive"
                                    onSelected: changeMainMenu(barIndex);
                                }
                            }
                    
                            Component.onCompleted: {
                                toolBar.children[1].setBadge("3");
                                toolBar.children[3].setBadge("12");
                            }
                        }
                    

                    The result is something like this:
                    alt text

                    My ToolBarButton have their opacity changing whether their state is Inactive, Hovered or Selected. When they emit the selected signal, the changeMainMenu function would change the state of the other buttons and the content of the main area (not sure yet how I'll achieve that, probably using a StackedView)

                        function changeMainMenu(selectedMenu){
                            console.log("New idx: "+selectedMenu)
                            for (var i = 0; i < toolBar.children.length; ++i)
                            {
                                if (i !== selectedMenu)
                                    toolBar.children[i].state = "Inactive";
                            }
                        }
                    
                    GrecKoG 1 Reply Last reply
                    0
                    • mbruelM mbruel

                      @GrecKo
                      Nice, thanks a lot!
                      Indeed it looks much better that way. I've checked the Repeater documentation and it's defo what I should use.
                      Here is the updated code which is nearly exactly what you gave me:

                          Row {
                              id: toolBar
                              anchors {
                                  bottom: parent.bottom
                                  bottomMargin: toolBarMargin;
                                  horizontalCenter: parent.horizontalCenter
                              }
                      
                              height:  toolBarHeight
                              spacing: toolBarSpacing
                      
                              Repeater {
                                  model: menuList
                                  ToolBarButton {
                                      id: button
                                      imagePath: "img/" + model.modelData + ".png"
                                      height: toolBar.height
                                      width: toolBarButtonWidth
                                      barIndex: model.index
                                      state: model.index === 0 ?  "Selected" : "Inactive"
                                      onSelected: changeMainMenu(barIndex);
                                  }
                              }
                      
                              Component.onCompleted: {
                                  toolBar.children[1].setBadge("3");
                                  toolBar.children[3].setBadge("12");
                              }
                          }
                      

                      The result is something like this:
                      alt text

                      My ToolBarButton have their opacity changing whether their state is Inactive, Hovered or Selected. When they emit the selected signal, the changeMainMenu function would change the state of the other buttons and the content of the main area (not sure yet how I'll achieve that, probably using a StackedView)

                          function changeMainMenu(selectedMenu){
                              console.log("New idx: "+selectedMenu)
                              for (var i = 0; i < toolBar.children.length; ++i)
                              {
                                  if (i !== selectedMenu)
                                      toolBar.children[i].state = "Inactive";
                              }
                          }
                      
                      GrecKoG Offline
                      GrecKoG Offline
                      GrecKo
                      Qt Champions 2018
                      wrote on last edited by GrecKo
                      #12

                      @mbruel said in How to add Items dynamically to a Row? (in javascript):

                      My ToolBarButton have their opacity changing whether their state is Inactive, Hovered or Selected. When they emit the selected signal, the changeMainMenu function would change the state of the other buttons and the content of the main area (not sure yet how I'll achieve that, probably using a StackedView)

                      That's still not very declarative :)
                      Act on your data, not your visual items.
                      Items should follow the data.

                      I believe my proposed solution is better, maybe relocate the currentIndex property if you want.

                      Your solution:

                                 // in your main or elsewhere:
                                 function changeMainMenu(selectedMenu) {
                                      for (var i = 0; i < toolBar.children.length; ++i) {
                                            if (i !== selectedMenu)    
                                                toolBar.children[i].state = "Inactive";
                                      }
                                  }
                                 // in your button
                                  state: model.index === 0 ?  "Selected" : "Inactive"
                                  onSelected: changeMainMenu(barIndex);
                      

                      You manipulate the properties of your items imperatively, you define in the state binding of the button (not really an actual binding since it will be overwritten by the changeMainMenu function anyway) that the first button is selected

                      My solution:

                                  // in the toolbar or elsewhere:
                                  property int selectedIndex: 0 // 0 is the initial selectedIndex
                                  // in your buttons
                                  state: barIndex === toolBar.selectedIndex ?  "Selected" : "Inactive"    
                                  onClicked: toolBar.selectedIndex = barIndex
                                  // ^ note that I changed it to a clicked signal, the button just tells how the user interacted with it
                                  //   it doesn't set itself as selected, the state binding does that.
                                  //   both your parent code and the button code becomes simpler
                      

                      @mbruel said in How to add Items dynamically to a Row? (in javascript):

                          Component.onCompleted: {
                              toolBar.children[1].setBadge("3");
                              toolBar.children[3].setBadge("12");
                          }
                      

                      Put that information in your model instead:

                      Repeater {
                          model: ListModel { // an array of JS objects would work here too
                              ListElement { image: "home"; badge: 0 }
                              ListElement { image: "mail"; badge: 3 }
                              ListElement { image: "compas"; badge: 0 }
                              ListElement { image: "stack"; badge: 12 }
                              ListElement { image: "profile"; badge: 0 } 
                          }
                          ToolBarButton {
                              ...
                              imagePath: "img/" + model.image+ ".png"
                              badge: model.badge
                          }
                      }
                      

                      Sorry if I'm being a purist, I just want to share my vision of how one should write QML ;)

                      I should also mention that I'm not a fan of the state property, but that's more opinion based.
                      In your case I would add a property bool selected property. Bind like so in the repeater: selected: model.index === selectedIndex
                      and in the button itself do: opacity: selected ? 1 : (hovered ? 0.7 : 0.4)

                      1 Reply Last reply
                      1
                      • mbruelM Offline
                        mbruelM Offline
                        mbruel
                        wrote on last edited by mbruel
                        #13

                        @GrecKo said in How to add Items dynamically to a Row? (in javascript):

                                state: barIndex === toolBar.selectedIndex ?  "Selected" : "Inactive"    
                                onClicked: toolBar.selectedIndex = barIndex
                        

                        Hum I don't catch something.... The "state binding" doesn't seem to work correctly.
                        When I click on a button, so the selectedIndex "main variable" is set to the index of my button but then the state of the other buttons is not updated due to the change of the value of selectedIndex.
                        What in your solution would trigger that? (What my changeMainMenu is actually doing)

                        Put that information in your model instead

                        Cool will do, it sounds better but for now it is just a mock, I would get this info from C++. Hum, still for the initialization I could use that ListModel. I didn't read the QML model view framework yet...

                        Sorry if I'm being a purist, I just want to share my vision of how one should write QML ;)

                        don't be sorry, that's exactly what I'm looking for, get the best practices asap. Thanks for helping ;)

                        I should also mention that I'm not a fan of the state property, but that's more opinion based.

                        well I'm not a big fan either of states but I saw that in an example and it seems the easiest way to use Transitions.

                        // an array of JS objects would work here too

                        how you do that?

                        Otherwise for the mainArea I used a Loader that is reloaded in my changeMainMenu function. How would this work with your solution?

                        Here is my full main.qml:

                        import QtQuick 2.12
                        import QtQuick.Window 2.12
                        
                        Window {
                            id: root
                        
                            visible: true
                            width: 400
                            height: 600
                            title: qsTr("my QML app!")
                        
                            property int toolBarIndex       : 0
                            property int toolBarHeight      : 50;
                            property int toolBarSpacing     : 15;
                            property int toolBarMargin      : 20;
                            property int toolBarButtonWidth : 50;
                        
                            property int headerButtonSize   : 30;
                            property int mainMargin         : 20;
                        
                        //    property var menuList : ["home", "mail", "compas", "stack", "profile"]
                            ListModel {
                                id: toolBarModel
                        
                                ListElement { name : "home"    ; badge: "0"  ; color: "lightgreen" }
                                ListElement { name : "mail"    ; badge: "3"  ; color: "lightblue" }
                                ListElement { name : "compas"  ; badge: "0"  ; color: "lightgray" }
                                ListElement { name : "stack"   ; badge: "12" ; color: "lightyellow" }
                                ListElement { name : "profile" ; badge: "0"  ; color: "ivory" }
                            }
                        
                            Rectangle {
                                id: background
                                anchors {
                                    fill: parent;
                                    margins: 0;
                                }
                                color: "green"
                                Image {
                                    source: "img/bg.png";
                                    fillMode: Image.Stretch;
                                    anchors.fill: parent;
                                    opacity: 1
                                }
                            }
                        
                        
                            Loader {
                                id: mainArea
                                anchors {
                                    top: parent.top
                                    left: parent.left
                                    topMargin: mainMargin + headerButtonSize / 2;
                                    bottomMargin: mainMargin
                                    leftMargin: mainMargin
                                    rightMargin: mainMargin
                                }
                                width: parent.width - 2*mainMargin
                                height: parent.height - 2*mainMargin - toolBarHeight - toolBarMargin
                            }
                        
                            ToolBarButton
                            {
                                id: search
                                anchors {
                                    top: parent.top
                                    left: parent.left
                                    margins: mainMargin;
                                }
                                width : headerButtonSize
                                height: headerButtonSize
                        
                                imagePath : "img/search.png"
                                state     : "Inactive"
                                selectable: false
                            }
                        
                            ToolBarButton
                            {
                                id: chat
                                anchors {
                                    top: parent.top
                                    right: parent.right
                                    margins: mainMargin;
                                }
                                width : headerButtonSize
                                height: headerButtonSize
                        
                                imagePath : "img/chat.png"
                                state     : "Inactive"
                                selectable: false
                            }
                        
                            Text {
                                text: title
                                anchors {
                                    top: parent.top
                                    horizontalCenter: parent.horizontalCenter
                                    topMargin: mainMargin;
                                }
                                color: "#ff0000"
                                font.pointSize: 24
                                font.bold: true
                            }
                        
                            function changeMainMenu(selectedMenu){
                                console.log("New idx: "+selectedMenu)
                                for (var i = 0; i < toolBar.children.length; ++i)
                                {
                                    if (i !== selectedMenu)
                                        toolBar.children[i].state = "Inactive";
                                }
                        
                                mainArea.setSource("SimpleMainArea.qml");
                                mainArea.item.lbl.text = toolBarModel.get(selectedMenu).name;//menuList[selectedMenu];
                                mainArea.item.color    = toolBarModel.get(selectedMenu).color;
                            }
                        
                        
                            Row {
                                id: toolBar
                                anchors {
                                    bottom: parent.bottom
                                    bottomMargin: toolBarMargin;
                                    horizontalCenter: parent.horizontalCenter
                                }
                        
                                height : toolBarHeight
                                spacing: toolBarSpacing
                        
                                Repeater {
                                    model: toolBarModel; //menuList
                                    ToolBarButton {
                                        id: button
                                        height: toolBar.height
                                        width: toolBarButtonWidth
                        
                        //                imagePath: "img/" + model.modelData + ".png"
                                        imagePath: "img/" + model.name + ".png"
                                        barIndex: model.index
                        //                state: root.toolBarIndex === barIndex ? "Selected" : "Inactive"
                        //                onSelected: root.toolBarIndex = barIndex
                                        state: barIndex === root.toolBarIndex ?  "Selected" : "Inactive"
                                        onSelected: changeMainMenu(barIndex)
                                    }
                                }
                        
                                Component.onCompleted: {
                                    for (var i = 0; i < toolBar.children.length; ++i)
                                        toolBar.children[i].setBadge(toolBarModel.get(i).badge);
                                }
                            }
                        
                            Component.onCompleted: {
                                changeMainMenu(0);
                            }
                        
                        }
                        
                        

                        The SimpleMainArea.qml

                        import QtQuick 2.0
                        import QtQuick.Controls 2.14
                        
                        Rectangle {
                            property alias lbl: lbl
                        
                            radius: 10
                            opacity: 0.8
                        
                            Text  {
                                id: lbl
                                anchors {
                                    horizontalCenter: parent.horizontalCenter
                                    verticalCenter: parent.verticalCenter;
                                }
                                text: "not set...";
                            }
                        }
                        

                        and my ToolBarButton.qml so you can tell me if you see bad practices ;)

                        import QtQuick 2.12
                        import QtQuick.Controls 2.14
                        
                        Item {
                            id: button
                        
                            property string imagePath;
                            property int    barIndex   : 0;
                            property bool   selectable : true;
                        
                            property color color: "transparent"
                        
                            property double opacityInactive: 0.2
                            property double opacityHover   : 0.4
                            property double opacitySelected: 1
                        
                            property int borderWidth : 0
                            property int borderRadius: 0
                        
                        
                            property string previousState: "Inactive";
                        
                            property color badgeColor : "#ec3e3a";  // redish color (exactly the one used in OS X 10.10)
                        
                        
                        
                            // Allow the programmer to define the text to display.
                            // Note that this control can display both text and numbers.
                        //    property alias badgeText: badgeLbl.text
                        
                        
                            signal selected(int idx);
                        
                        
                        
                            //RectangItemle to draw the button
                            Rectangle {
                                id: rect
                        
                                anchors.fill: parent
                                radius: borderRadius
                                color: button.enabled ? button.color : "grey"
                        
                                border.width: borderWidth
                                border.color: "black"
                        
                                opacity: opacityInactive
                        
                                Image {
                                    id: img
                                    anchors.fill: parent;
                                    source: imagePath;
                                    fillMode: Image.PreserveAspectFit;
                                }
                            }
                        
                            Rectangle {
                                id: badge
                        
                                visible: false
                                smooth: true
                        
                                // Create an animation when the opacity changes
                                Behavior on opacity {NumberAnimation{}}
                        
                                // Setup the anchors so that the badge appears on the bottom right
                                // area of its parent
                                anchors.right: rect.right
                                anchors.top: rect.top
                        
                                // This margin allows us to be "a little outside" of the object in which
                                // we add the badge
                        //        anchors.margins: -parent.width / 5 + device.ratio(1)
                        
                                color: badgeColor
                        
                                // Make the rectangle a circle
                                radius: width / 2
                        
                                // Setup height of the rectangle (the default is 18 pixels)
                                height: 18
                        
                                // Make the rectangle and ellipse if the length of the text is bigger than 2 characters
                                width: badgeLbl.text.length > 2 ? badgeLbl.paintedWidth + height / 2 : height
                        
                                // Create a label that will display the number of connected users.
                                Label {
                                    id: badgeLbl
                                    color: "#fdfdfdfd"
                                    font.pixelSize: 9
                                    anchors.fill: parent
                                    verticalAlignment: Text.AlignVCenter
                                    horizontalAlignment: Text.AlignHCenter
                        
                                    // We need to have the same margins as the badge so that the text
                                    // appears perfectly centered inside its parent.
                                    anchors.margins: parent.anchors.margins
                                }
                            }
                        
                        
                            //Mouse area to react on click events
                            MouseArea {
                                hoverEnabled: true
                                anchors.fill: button
                                onEntered: {
                                    button.previousState = button.state;
                                    if (button.state != 'Selected')
                                        button.state='Hover';
                        
                                }
                        
                                onExited : { button.state = previousState; }
                        
                                onClicked: {
                                    if (selectable)
                                    {
                                        button.previousState = 'Selected';
                                        button.state         = 'Selected';
                                    }
                                    button.selected(button.barIndex);
                                }
                            }
                        
                        
                            function setBadge(msg)
                            {
                                if (msg !== "" && msg !== "0")
                                {
                                    badge.visible = true;
                                    badgeLbl.text = msg;
                        
                                    badge.width = badgeLbl.text.length > 2 ? badgeLbl.paintedWidth + badgeLbl.height / 2 : badgeLbl.height;
                                }
                                else
                                    badge.visible = false;
                        
                            }
                        
                            function clearBadge() {badge.visible = false;}
                        
                        
                            //change the color of the button in differen button states
                            states: [
                                State {
                                    name: "Inactive"
                                    PropertyChanges {
                                        target : rect
                                        opacity: opacityInactive
                                    }
                                },
                                State {
                                    name: "Hover"
                                    PropertyChanges {
                                        target : rect
                                        opacity: opacityHover
                                    }
                                },
                                State {
                                    name: "Selected"
                                    PropertyChanges {
                                        target : rect
                                        opacity: opacitySelected
                                    }
                                }
                            ]
                        
                            state: previousState;
                        
                        
                            //define transmission for the states
                            transitions: [
                                Transition {
                                    from: ""; to: "Hover"
                                    OpacityAnimator { duration: 200 }
                                },
                                Transition {
                                    from: "*"; to: "Selected"
                                    OpacityAnimator { duration: 10 }
                                }
                            ]
                        }
                        

                        Edit: here is a small video of the desired behaviour

                        Edit2: my commented

                        //                state: root.toolBarIndex === barIndex ? "Selected" : "Inactive"
                        //                onSelected: root.toolBarIndex = barIndex
                        

                        is not stable, it is working the first time but then it seems the change of root.toolBarIndex doesn't impact all the buttons.. Any idea why?

                        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