QML Tableview resize column width by dragging the column header border
-
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 }
-
@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
inreturn temp
section, but the value is not properly updated in TableViewimport 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)) } } } } } }
-
I have solved the issue using
QtQuick.Controls 1.2
. Posting the solution for someone if it helpsimport 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" } } } } }
-
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{ }