Qt QML中如何让TableView列宽自适应窗口并支持拖拽调整?
QML实现TableView列宽自适应窗口+拖拽调整
针对Qt 6.8.3版本,要实现表格列宽自适应窗口宽度(左右边界与窗口对齐)且支持鼠标拖拽修改列宽,可通过以下方式实现:
核心修改点
- 用
columnWidthProvider动态计算列宽,同时保存用户手动调整的列宽值 - 监听窗口尺寸变化,触发表格重新布局
- 保留
resizableColumns: true以支持拖拽调整列宽
修改后的完整代码
import QtQuick import Qt.labs.qmlmodels import QtQuick.Controls Window { width: 640 height: 480 visible: true title: qsTr("table modle view") // 保存用户调整后的列宽,-1表示自动分配 ListModel { id: columnWidthsModel ListElement { width: -1 } ListElement { width: -1 } ListElement { width: -1 } ListElement { width: -1 } } TableModel { id: contactsModel TableModelColumn { display: "firstName" } TableModelColumn { display: "lastName" } TableModelColumn { display: "age" } TableModelColumn { display: "phoneNumber" } rows: [ { firstName: "John", lastName: "Doe", age: "49", phoneNumber: "111-111-1111" }, { firstName: "Jane", lastName: "Doe", age: "48", phoneNumber: "222-222-2222" }, { firstName: "George", lastName: "Doe", age: "12", phoneNumber: "333-333-3333" }, ] } Component { id: contactsDelegate Rectangle { id: delegateRect required property bool current implicitHeight: 50 color: current ? "pink" : "lightgray" border.width: current ? 2 : 0 TableView.editDelegate: contactsEditDelegate Text { text: model.display padding: 12 anchors.fill: parent } } } ScrollView { id: scrollView anchors.top: contactsHHeader.bottom anchors.bottom: parent.bottom anchors.left: contactsVHeader.right anchors.right: parent.right TableView { id: contactsView anchors.fill: parent columnSpacing: 1 rowSpacing: 1 resizableColumns: true resizableRows: true model: contactsModel delegate: contactsDelegate selectionModel: ItemSelectionModel { model: contactsView.model } // 动态提供列宽 columnWidthProvider: function(column) { const savedWidth = columnWidthsModel.get(column).width if (savedWidth !== -1) { return savedWidth } // 自动分配:平均分配可用宽度,扣除列间距 const availableWidth = scrollView.width - (columnSpacing * (contactsModel.columnCount - 1)) return availableWidth / contactsModel.columnCount } // 保存用户手动调整的列宽 onColumnWidthChanged: { columnWidthsModel.setProperty(column, "width", width) } } } HorizontalHeaderView { id: contactsHHeader anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: contactsVHeader.width anchors.top: parent.top implicitHeight: 50 syncView: contactsView textRole: "display" model: ListModel { ListElement{display: "First Name"} ListElement{display: "Last Name"} ListElement{display: "Age"} ListElement{display: "Phone Number"} } delegate: Rectangle { color: "#168bcd" Text { anchors.centerIn: parent text: model.display padding: 12 } } } VerticalHeaderView{ id: contactsVHeader anchors.left: parent.left anchors.top: parent.top anchors.topMargin: contactsHHeader.height syncView: contactsView } Component { id: contactsEditDelegate TextField { anchors.fill: parent text: model.display horizontalAlignment: TextInput.AlignHCenter verticalAlignment: TextInput.AlignVCenter TableView.onCommit: { let index = TableView.view.index(model.row, model.column) model.display = text } } } // 窗口宽度变化时,强制表格重新布局以更新列宽 onWidthChanged: { contactsView.forceLayout() } }
代码说明
columnWidthsModel:存储用户手动调整后的列宽,初始值-1表示该列需要自动分配宽度columnWidthProvider:- 如果用户调整过某列宽度,直接返回保存的值
- 未调整过的列,按平均比例分配
ScrollView的可用宽度(扣除列间距)
onColumnWidthChanged:监听列宽拖拽事件,将用户调整后的宽度保存到模型中onWidthChanged:窗口宽度变化时,调用forceLayout()触发表格重新计算列宽,确保表格始终填满窗口
内容的提问来源于stack exchange,提问作者shanw
相关产品推荐
相关产品推荐

