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. QML Tableview resize column width by dragging the column header border
Forum Updated to NodeBB v4.3 + New Features

QML Tableview resize column width by dragging the column header border

Scheduled Pinned Locked Moved Solved QML and Qt Quick
5 Posts 2 Posters 3.5k 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.
  • C Offline
    C Offline
    chilarai
    wrote on last edited by
    #1

    I want to resize the column width of a table by dragging the column header border as it can be done in MS Excel. The following code is for my generated table. By default, it is not enabled in TableView (listed here https://doc.qt.io/qt-5/qml-qtquick-tableview-members.html). What am I missing?

    import QtQuick 2.15
    import QtQuick.Controls 2.15
    import QtQuick.Layouts 1.3
    
    
    TableView {
        id: dataPreviewResult
    
        columnWidthProvider: function (column) { return 100; }
        rowHeightProvider: function (column) { return 30; }
        anchors.fill: parent
        topMargin: columnsHeader1.implicitHeight
        width: parent.width
        ScrollBar.horizontal: ScrollBar{}
        ScrollBar.vertical: ScrollBar{}
        clip: true
        boundsBehavior : Flickable.StopAtBounds
    
    
        Connections{
            target: QueryModel
    
            function onSqlHasData(hasData){
                dataPreviewResult.model = hasData === true? QueryModel: ""
            }
    
            function onHeaderDataChanged(tableHeaders){
                mainRepeater.model = tableHeaders
            }
    
        }
    
        delegate: Rectangle {
            border.color: Constants.darkThemeColor
            border.width: 0.5
    
            Text {
                text: display
                anchors.fill: parent
                anchors.margins: 10
                verticalAlignment: Text.AlignVCenter
                elide: Text.ElideRight
                color: Constants.lightGrayTextColor
            }
        }
        Rectangle { // mask the headers
            z: 3
            y: dataPreviewResult.contentY
            x: dataPreviewResult.contentX
            width: dataPreviewResult.leftMargin
            height: dataPreviewResult.topMargin
            border.color: Constants.themeColor
            border.width: 0.2
        }
    
        // Table Header Starts
    
        Row {
            id: columnsHeader1
            y: dataPreviewResult.contentY
            z: 2
            width: dataPreviewResult.width
    
            Repeater {
                id: mainRepeater
    
                Rectangle{
                    width: dataPreviewResult.columnWidthProvider(modelData)
                    height: 30
                    border.color: Constants.darkThemeColor
                    color: Constants.lightThemeColor
                    border.width: 1
    
                    Text {
                        id: textName
                        text: modelData
                        width: parent.width
                        height: parent.height
                        anchors.centerIn: parent
                        padding: 10
                        font.bold: false
                        verticalAlignment: Text.AlignVCenter
                    }
                }
            }
        }
    
        Layout.fillWidth: true
        Layout.fillHeight: true
    
    }
    
    
    1 Reply Last reply
    0
    • fcarneyF Offline
      fcarneyF Offline
      fcarney
      wrote on last edited by
      #2

      I don't know if there is a way to do that with the TableView from qtquick.controls 2. I know we do it with TableView from qtquick.controls 1. I am not sure, but for QC1 I think it is controlled via the style.

      C++ is a perfectly valid school of magic.

      1 Reply Last reply
      0
      • C Offline
        C Offline
        chilarai
        wrote on last edited by chilarai
        #3

        @fcarney , yes you are right. Its available in QC1. But there again I am facing an issue while dynamically updating column headers (including column count) using resources property. It seems my code below only updates the values and not the column headers and count. I would be glad if you can point out my mistake?

        I am trying to update the TableView using signals and slots whenever I have a new value. The updated value is returned from the resources in return temp section, but the value is not properly updated in TableView

        import QtQuick 2.3
        import QtQuick.Window 2.2
        import QtQuick.Controls 1.2
        import QtQuick.Controls.Styles 1.2
        
        Rectangle {
            id: win
            width: 860
            height: 560
            visible: true
        
            property var roleNames:["a", "b", "c"]
            property var i : 0
            property var previousModelData : 0
            property var newObject: []
        
            Connections{
                target: QueryModel
        
                // This one is for table data
                // It functions fine
                function onSqlHasData(hasData){
                    view.model = hasData === true? QueryModel: ""
                }
        
                // This slot is for updating headers
                // This is also returning an array of strings
                // It is fired before the above onSqlHasData slot
                function onHeaderDataChanged(tableHeaders){
                    if(tableHeaders.length > 0){
                        roleNames = tableHeaders
                    }
                }
            }
        
            Component{
                id:columnComponent
                TableViewColumn {
                    width: 100
                }
            }
        
            TableView {
                id:view
                width: parent.width
                height: parent.height
                alternatingRowColors: false
        
                resources: {
                    var roleList = roleNames
                    var temp = []
                    for(var i=0; i<roleList.length; i++)
                    {
                        var role  = roleList[i]
                        temp.push(columnComponent.createObject(view, { "role": role, "title": role}))
                    }
                    // I can see that the return value below 
                    // is updated whenever I a receiving a new value
                    // But the view is not updated
                    return temp
                }
        
                headerDelegate: Rectangle {
                    height: textItem.implicitHeight * 1.2
                    width: textItem.implicitWidth
                    color: "lightgrey"
                    Text {
                        id: textItem
                        anchors.fill: parent
                        verticalAlignment: Text.AlignVCenter
                        horizontalAlignment: styleData.textAlignment
                        anchors.leftMargin: 12
                        text: roleNames[styleData.column]
                        elide: Text.ElideRight
                        color: textColor
                        renderType: Text.NativeRendering
                    }
        
                }
        
                itemDelegate: Rectangle {
                    width: dataPreviewResult.columnWidthProvider(modelData)
                    color: "white"
                    objectName: modelData
        
                    Text {
                        id: textItem1
                        anchors.fill: parent
                        objectName: modelData
                        verticalAlignment: Text.AlignVCenter
                        horizontalAlignment: styleData.textAlignment
                        anchors.leftMargin: 12
                        elide: Text.ElideRight
                        color: textColor
                        renderType: Text.NativeRendering
                        onObjectNameChanged: {
                            if(previousModelData === modelData){
                                i++
                                textItem1.text = QueryModel.data(QueryModel.index(modelData-1,i))
                            } else{
                                i = 0;
                                previousModelData = modelData
                                textItem1.text = QueryModel.data(QueryModel.index(previousModelData - 1,i))
                            }
                        }
                    }
        
                }
            }
        }
        
        1 Reply Last reply
        0
        • C Offline
          C Offline
          chilarai
          wrote on last edited by chilarai
          #4

          I have solved the issue using QtQuick.Controls 1.2. Posting the solution for someone if it helps

          import QtQuick 2.3
          import QtQuick.Window 2.2
          import QtQuick.Controls 1.2
          import QtQuick.Controls.Styles 1.2
          
          Rectangle {
              id: win
              width: 860
              height: 560
              visible: true
          
              property var roleNames:["a", "b", "c"]
              property var newObject: []
          
              Connections{
                  target: QueryModel
          
                  // This one is for table data
                  function onSqlHasData(hasData){
                      view.model = hasData === true? QueryModel: ""
          
                  }
          
                  // This slot is for updating headers
                  // This is also returning an array of strings
                  function onHeaderDataChanged(tableHeaders){
                      if(tableHeaders.length > 0){
                          roleNames = []
                          roleNames = tableHeaders
          
                          for(var i=0; i<roleNames.length; i++){
                              var role  = roleNames[i]
                              var columnString = 'import QtQuick 2.3; import QtQuick.Controls 1.2; TableViewColumn {role: "' + role + '"; title: "' + role + '"; }';
                              newObject[i] = Qt.createQmlObject(columnString, view)
                              view.addColumn(newObject[i])
                          }
                      }
                  }
          
              }
          
              // This one is to clear the table
              function clearTable(){
                  for(var i=0; i<roleNames.length; i++){
                      view.removeColumn(newObject[i])
                      delete newObject[i]
          
                  }
              }
          
          
              Button{
                  id: clearBtn
                  text: "Clear"
                  height: 30
                  onClicked: clearTable()
              }
          
              TableView {
                  id:view
                  width: parent.width
                  height: parent.height - clearBtn.height
                  anchors.top: clearBtn.bottom
                  alternatingRowColors: false
                  style: TableViewStyle {
                      headerDelegate: Rectangle {
                          height: textItem.implicitHeight * 1.2
                          width: textItem.implicitWidth
                          color: "lightgrey"
                          Text {
                              id: textItem
                              anchors.fill: parent
                              verticalAlignment: Text.AlignVCenter
                              horizontalAlignment: styleData.textAlignment
                              anchors.leftMargin: 12
                              text: styleData.value
                              elide: Text.ElideRight
                              color: textColor
                              renderType: Text.NativeRendering
          
                          }
                          Rectangle {
                              anchors.right: parent.right
                              anchors.top: parent.top
                              anchors.bottom: parent.bottom
                              anchors.bottomMargin: 1
                              anchors.topMargin: 1
                              width: 1
                              color: "black"
                              border.color: "black"
                          }
                          Rectangle {
                              anchors.bottom: parent.bottom
                              width: parent.width
                              height: 1
                              color: "black"
                              border.color: "black"
                          }
                      }
          
                      itemDelegate: Rectangle {
                          color: "white"
                          Text {
                              id: textItem1
                              anchors.fill: parent
                              verticalAlignment: Text.AlignVCenter
                              horizontalAlignment: styleData.textAlignment
                              anchors.leftMargin: 12
                              text: modelData
                              elide: Text.ElideRight
                              color: textColor
                              renderType: Text.NativeRendering
                          }
                          Rectangle {
                              anchors.right: parent.right
                              anchors.top: parent.top
                              anchors.bottom: parent.bottom
                              width: 1
                              color: "black"
                              border.color: "black"
                          }
                          Rectangle {
                              anchors.bottom: parent.bottom
                              width: parent.width
                              height: 1
                              color: "black"
                              border.color: "black"
                          }
                      }
                  }
              }
          }
          
          1 Reply Last reply
          1
          • fcarneyF Offline
            fcarneyF Offline
            fcarney
            wrote on last edited by fcarney
            #5

            Sorry I didn't mention it. But you can pick and choose from different libraries by using the "as" clause on import. For instance if you want Quick.Controls 1 and 2 in same file you can do this:

            import QtQuick.Controls 2.15
            import QtQuick.Controls 1.2 as QC1
            ...
            QC1.TableView{
            }
            

            C++ is a perfectly valid school of magic.

            1 Reply Last reply
            1

            • Login

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