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
Forum Updated to NodeBB v4.3 + New Features

Adding TabButton dynamically to TabBar

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qtquick2qtquickcontrolsqtquickcontroltabbutton
14 Posts 4 Posters 9.5k 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 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
    • ODБOïO ODБOï

      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 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
      • ODБOïO Offline
        ODБOïO Offline
        ODБOï
        wrote on 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
        1
        • ODБOïO ODБOï

          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 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 ..

          ODБOïO 1 Reply Last reply
          0
          • P pra7

            @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 ..

            ODБOïO Offline
            ODБOïO Offline
            ODБOï
            wrote on 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
            • ODБOïO Offline
              ODБOïO Offline
              ODБOï
              wrote on 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
              • ODБOïO Offline
                ODБOïO Offline
                ODБOï
                wrote on last edited by
                #6

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

                P 1 Reply Last reply
                0
                • ODБOïO ODБOï

                  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 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
                  • ODБOïO ODБOï

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

                    P Offline
                    P Offline
                    pra7
                    wrote on last edited by
                    #8

                    @LeLev Thanks for all your suggestions....

                    1 Reply Last reply
                    1
                    • ODБOïO Offline
                      ODБOïO Offline
                      ODБOï
                      wrote on last edited by
                      #9

                      You are welcome :)

                      1 Reply Last reply
                      0
                      • ODБOïO Offline
                        ODБOïO Offline
                        ODБOï
                        wrote on 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
                        • ODБOïO Offline
                          ODБOïO Offline
                          ODБOï
                          wrote on 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
                          1
                          • ODБOïO ODБOï

                            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 last edited by
                            #12

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

                            E 1 Reply Last reply
                            0
                            • P pra7

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

                              E Offline
                              E Offline
                              Eeli K
                              wrote on 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
                              • GrecKoG Offline
                                GrecKoG Offline
                                GrecKo
                                Qt Champions 2018
                                wrote on 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

                                • Login

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