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. Adding TabButton dynamically to TabBar
QtWS25 Last Chance

Adding TabButton dynamically to TabBar

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qtquick2qtquickcontrolsqtquickcontroltabbutton
14 Posts 4 Posters 9.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    pra7
    wrote on 27 Jul 2017, 11:47 last edited by pra7
    #1

    I am trying to add a tabButton to TabBar dynamically on pressing a button but i have spent a lot of time searching but i am not getting how to add, below is the code which i am working on :

    MyTabButton.qml

    import QtQuick 2.4
    import QtQuick.Controls 2.2
    
    Item
    {
        property int BtnWidth:0
        property int BtnHeight:0
        property string BtnText: ""
        property bool isChecked : false
    
        TabButton
        {
            id:tabBtn
            text:BtnText
            width:BtnWidth
            height:BtnHeight
    
        }
    }
    

    MainForm.qml

    import QtQuick 2.4
    import QtQuick.Controls 2.2
    
    Rectangle
    {
        Button
        {
            id:button
            width:100
            height:100
            anchors.top:parent.top
            text:qStr("Add")
            onClicked{
                //How to add logic here to add tab in below tabBar.
            }
        }
        TabBar
        {
            id:tabBar
            anchors.top:button.bottom
            width:500
            height:500
        }
    }
    
    1 Reply Last reply
    0
    • O ODБOï
      27 Jul 2017, 13:13

      Hello,

      this is one way to do that using Repeater type.

      import QtQuick 2.0
      import QtQuick.Window 2.2
      import QtQuick.Controls 2.0
      import QtQuick.Layouts 1.3

      Window {
      visible: true
      width: 640
      height: 480

          Button
          {
              id:button
              width:100
              height:100
              anchors.top:parent.top
              text:"add"//qStr("Add")
              onClicked:{
      
                      tabBtnRepeater.model ++
      
              }
          }
      
          TabBar
          {
              id:tabBar
              anchors.top:button.bottom
              width:500
              height:500
      
              Repeater{
                  id: tabBtnRepeater
      
                  model : 0 //
      
                  TabButton{
                      width: 100
                      text: "Btn n° " + index
                  }
      
              }
      
      
          }
      }
      

      LA

      P Offline
      P Offline
      pra7
      wrote on 27 Jul 2017, 14:52 last edited by pra7
      #7

      @LeLev In my question, you can see that TabButton is created in a separate file. So, based on index changed event I need to do some stuff inside doSomething() on all the TabButtons present in the TabBar.

      I got the solution by using the Component as below :

      in MainForm.Qml

      Component {
             id: myTabButton
             MyTabButton {
                 Connections {
                     target: tabBar
                     onCurrentIndexChanged: doSomething()
                 }
            }
         }
      
      Button
         {
             id:button
             width:100
             height:100
             anchors.top:parent.top
             text:qStr("Add")
             onClicked{
             // A object out of the component, and adding it to the container
             onClicked: tabBar.addItem(myTabButton.createObject(tabBar /*, { object to set properties }*/))
         }
      

      Thus Whenever an index is changed doSomething function will be called.

      1 Reply Last reply
      1
      • O Offline
        O Offline
        ODБOï
        wrote on 27 Jul 2017, 13:13 last edited by
        #2

        Hello,

        this is one way to do that using Repeater type.

        import QtQuick 2.0
        import QtQuick.Window 2.2
        import QtQuick.Controls 2.0
        import QtQuick.Layouts 1.3

        Window {
        visible: true
        width: 640
        height: 480

            Button
            {
                id:button
                width:100
                height:100
                anchors.top:parent.top
                text:"add"//qStr("Add")
                onClicked:{
        
                        tabBtnRepeater.model ++
        
                }
            }
        
            TabBar
            {
                id:tabBar
                anchors.top:button.bottom
                width:500
                height:500
        
                Repeater{
                    id: tabBtnRepeater
        
                    model : 0 //
        
                    TabButton{
                        width: 100
                        text: "Btn n° " + index
                    }
        
                }
        
        
            }
        }
        

        LA

        P 2 Replies Last reply 27 Jul 2017, 14:05
        1
        • O ODБOï
          27 Jul 2017, 13:13

          Hello,

          this is one way to do that using Repeater type.

          import QtQuick 2.0
          import QtQuick.Window 2.2
          import QtQuick.Controls 2.0
          import QtQuick.Layouts 1.3

          Window {
          visible: true
          width: 640
          height: 480

              Button
              {
                  id:button
                  width:100
                  height:100
                  anchors.top:parent.top
                  text:"add"//qStr("Add")
                  onClicked:{
          
                          tabBtnRepeater.model ++
          
                  }
              }
          
              TabBar
              {
                  id:tabBar
                  anchors.top:button.bottom
                  width:500
                  height:500
          
                  Repeater{
                      id: tabBtnRepeater
          
                      model : 0 //
          
                      TabButton{
                          width: 100
                          text: "Btn n° " + index
                      }
          
                  }
          
          
              }
          }
          

          LA

          P Offline
          P Offline
          pra7
          wrote on 27 Jul 2017, 14:05 last edited by
          #3

          @LeLev .. Thanks for the answer and Is there any way to get the each TabButton item which is created in Repeater ? .
          I need to call some function on the fly in "TabBar" curentIndexChanged event handler ..

          O 1 Reply Last reply 27 Jul 2017, 14:38
          0
          • P pra7
            27 Jul 2017, 14:05

            @LeLev .. Thanks for the answer and Is there any way to get the each TabButton item which is created in Repeater ? .
            I need to call some function on the fly in "TabBar" curentIndexChanged event handler ..

            O Offline
            O Offline
            ODБOï
            wrote on 27 Jul 2017, 14:38 last edited by
            #4

            @pra7

            I cant understant what exactly are you trying to do.

            in "TabBar" curentIndexChanged event handler i guess you will do some action depending which button is clicked right ?

            You can do that by simply adding an 'onClicked' handler on your TabButton like this :

            TabButton{
            width: 100
            text: "Btn n° " + index
            onClicked { console.log(index) } // for exemple
            }

            LA

            1 Reply Last reply
            0
            • O Offline
              O Offline
              ODБOï
              wrote on 27 Jul 2017, 14:42 last edited by
              #5

              This can help you to access repeater Itemes:
              https://stackoverflow.com/questions/13270818/how-to-access-the-properties-of-a-repeaters-children-in-qml

              and this, if you want to try an other approche (Dynamic Qml Object creation )
              http://doc.qt.io/qt-5/qtqml-javascript-dynamicobjectcreation.html

              LA

              1 Reply Last reply
              1
              • O Offline
                O Offline
                ODБOï
                wrote on 27 Jul 2017, 14:46 last edited by
                #6

                https://forum.qt.io/topic/36501/solved-add-remove-tabs-dynamically/3

                P 1 Reply Last reply 27 Jul 2017, 14:54
                0
                • O ODБOï
                  27 Jul 2017, 13:13

                  Hello,

                  this is one way to do that using Repeater type.

                  import QtQuick 2.0
                  import QtQuick.Window 2.2
                  import QtQuick.Controls 2.0
                  import QtQuick.Layouts 1.3

                  Window {
                  visible: true
                  width: 640
                  height: 480

                      Button
                      {
                          id:button
                          width:100
                          height:100
                          anchors.top:parent.top
                          text:"add"//qStr("Add")
                          onClicked:{
                  
                                  tabBtnRepeater.model ++
                  
                          }
                      }
                  
                      TabBar
                      {
                          id:tabBar
                          anchors.top:button.bottom
                          width:500
                          height:500
                  
                          Repeater{
                              id: tabBtnRepeater
                  
                              model : 0 //
                  
                              TabButton{
                                  width: 100
                                  text: "Btn n° " + index
                              }
                  
                          }
                  
                  
                      }
                  }
                  

                  LA

                  P Offline
                  P Offline
                  pra7
                  wrote on 27 Jul 2017, 14:52 last edited by pra7
                  #7

                  @LeLev In my question, you can see that TabButton is created in a separate file. So, based on index changed event I need to do some stuff inside doSomething() on all the TabButtons present in the TabBar.

                  I got the solution by using the Component as below :

                  in MainForm.Qml

                  Component {
                         id: myTabButton
                         MyTabButton {
                             Connections {
                                 target: tabBar
                                 onCurrentIndexChanged: doSomething()
                             }
                        }
                     }
                  
                  Button
                     {
                         id:button
                         width:100
                         height:100
                         anchors.top:parent.top
                         text:qStr("Add")
                         onClicked{
                         // A object out of the component, and adding it to the container
                         onClicked: tabBar.addItem(myTabButton.createObject(tabBar /*, { object to set properties }*/))
                     }
                  

                  Thus Whenever an index is changed doSomething function will be called.

                  1 Reply Last reply
                  1
                  • O ODБOï
                    27 Jul 2017, 14:46

                    https://forum.qt.io/topic/36501/solved-add-remove-tabs-dynamically/3

                    P Offline
                    P Offline
                    pra7
                    wrote on 27 Jul 2017, 14:54 last edited by
                    #8

                    @LeLev Thanks for all your suggestions....

                    1 Reply Last reply
                    1
                    • O Offline
                      O Offline
                      ODБOï
                      wrote on 27 Jul 2017, 14:57 last edited by
                      #9

                      You are welcome :)

                      1 Reply Last reply
                      0
                      • O Offline
                        O Offline
                        ODБOï
                        wrote on 27 Jul 2017, 15:07 last edited by
                        #10

                        Full version with normal 'TabButton' :

                        import QtQuick 2.0
                        import QtQuick.Window 2.2
                        import QtQuick.Controls 2.0
                        import QtQuick.Layouts 1.3

                        Window {
                        visible: true
                        width: 640
                        height: 480

                        function doSomething(){
                            console.log(tabBar.currentIndex)
                        }
                        
                        Component {
                               id: myTabButton
                               TabButton {
                                   Connections {
                                       target: tabBar
                                       onCurrentIndexChanged: doSomething()
                                   }
                              }
                           }
                        
                        
                            Button
                            {
                                id:button
                                width:100
                                height:100
                                anchors.top:parent.top
                                text:"add"
                                onClicked:{
                                        tabBar.addItem(myTabButton.createObject(tabBar ))
                                    
                                }
                            }
                        
                            TabBar
                            {
                                id:tabBar
                                anchors.top:button.bottom
                                width:500
                                height:500
                        
                            }
                        }
                        

                        I'm still intrigued by one thing ! why doSomething() is called 2 times ??
                        LA

                        1 Reply Last reply
                        0
                        • O Offline
                          O Offline
                          ODБOï
                          wrote on 27 Jul 2017, 15:11 last edited by
                          #11

                          It is not called 2 times but 'addedButtonNumber' times

                          if we have 2 btns it is called 2 times
                          if we have 3, 3 times and so on

                          LA

                          P 1 Reply Last reply 27 Jul 2017, 15:25
                          1
                          • O ODБOï
                            27 Jul 2017, 15:11

                            It is not called 2 times but 'addedButtonNumber' times

                            if we have 2 btns it is called 2 times
                            if we have 3, 3 times and so on

                            LA

                            P Offline
                            P Offline
                            pra7
                            wrote on 27 Jul 2017, 15:25 last edited by
                            #12

                            @LeLev Yes .. it will be called based on TabBar.Count ...

                            E 1 Reply Last reply 28 Jul 2017, 08:29
                            0
                            • P pra7
                              27 Jul 2017, 15:25

                              @LeLev Yes .. it will be called based on TabBar.Count ...

                              E Offline
                              E Offline
                              Eeli K
                              wrote on 28 Jul 2017, 08:29 last edited by
                              #13

                              @pra7 createObject may be the best solution for you. As an exercise I tried another way:

                              import QtQuick 2.6
                              import QtQuick.Layouts 1.3
                              import QtQuick.Controls 2.1
                              
                              ApplicationWindow {
                                  id: window
                                  width: 360
                                  height: 520
                                  visible: true
                              
                              
                                  ColumnLayout
                                  {
                                      Button
                                      {
                                          id:button
                                          text:"add"
                                          onClicked: {
                                              control.contentItem.model.append({"text":"x"})
                                          }
                                      }
                                      TabBar
                                      {
                                          {
                                          Layout.fillWidth: true
                                          id: control
                              
                                          contentItem: ListView {
                                              implicitWidth: contentWidth
                                              implicitHeight: 40
                              
                                              model: ListModel{}
                                              delegate: TabButton{text:model.modelData}
                                              currentIndex: control.currentIndex
                              
                                              spacing: control.spacing
                                              orientation: ListView.Horizontal
                                              boundsBehavior: Flickable.StopAtBounds
                                              flickableDirection: Flickable.AutoFlickIfNeeded
                                              snapMode: ListView.SnapToItem
                              
                                              highlightMoveDuration: 0
                                              highlightRangeMode: ListView.ApplyRange
                                              preferredHighlightBegin: 40
                                              preferredHighlightEnd: width - 40
                                          }
                                      }
                                  }
                              }
                              

                              The TabBar code is taken partly from Default style's TabBar.qml to make it look and behave indentically.

                              1 Reply Last reply
                              1
                              • G Offline
                                G Offline
                                GrecKo
                                Qt Champions 2018
                                wrote on 28 Jul 2017, 08:49 last edited by GrecKo
                                #14

                                Simpler alternative, just a Repeater with a ListModel inside TabBar :

                                import QtQuick 2.0
                                import QtQuick.Window 2.2
                                import QtQuick.Controls 2.0
                                
                                ApplicationWindow {
                                    visible: true
                                    width: 640
                                    height: 480
                                
                                    ListModel {
                                        id: tabModel
                                    }
                                
                                    TabBar
                                    {
                                        Repeater {
                                            model: tabModel
                                            TabButton {
                                                text: model.text + " " + model.index
                                                onClicked: tabModel.remove(model.index)
                                            }
                                        }
                                    }
                                
                                    Button
                                    {
                                        anchors.centerIn: parent
                                        text:"add"
                                        onClicked: tabModel.append({text: "tab"});
                                    }
                                }
                                

                                EDIT: My bad, I didn't saw @LeLev first answer, it's very similar to mine. But I fell compelled to post it cause there's a lot of over complicated code in the following answers.

                                1 Reply Last reply
                                0

                                8/14

                                27 Jul 2017, 14:54

                                • Login

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