HusTableView 表格
April 14, 2026 · View on GitHub
HusTableView 表格
展示行列数据。
-
模块 { HuskarUI.Basic }
-
继承自 { HusRectangle }
支持的代理:
-
columnHeaderDelegate: Component 列头代理,代理可访问属性:
-
model: var列模型数据 -
headerData: var列描述数据(即columns[column]) -
column: int列索引
-
-
rowHeaderDelegate: Component 行头代理,代理可访问属性:
-
model: var行模型数据 -
row: int行索引
-
-
columnHeaderTitleDelegate: Component 列头标题代理,代理可访问属性:
-
align: string该列标题的对齐 -
headerData: var列描述数据(即columns[column]) -
column: int列索引
-
-
columnHeaderSorterIconDelegate: Component 列头搜索器图标代理,代理可访问属性:
-
sorter: var该列的搜索器 -
sortDirections: list该列的搜索方向数组 -
column: int列索引
-
-
columnHeaderFilterIconDelegate: Component 列头过滤器图标代理,代理可访问属性:
-
onFilter: var该列的过滤器 -
column: int列索引
-
支持的属性:
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| animationEnabled | bool | HusTheme.animationEnabled | 是否开启动画 |
| reuseItems | bool | false | 是否重用项目(具体参考官方文档) |
| propagateWheelEvent | bool | false | 是否传播鼠标滚轮事件 |
| alternatingRow | bool | false | 是否交替显示行背景 |
| defaultColumnHeaderHeight | int | 40 | 默认列头高度 |
| defaultRowHeaderWidth | int | 40 | 默认行头宽度 |
| showColumnGrid | bool | false | 是否显示列网格线 |
| showRowGrid | bool | false | 是否显示行网格线 |
| columnResizable | bool | true | 是否可调整列大小 |
| rowResizable | bool | true | 是否可调整行大小 |
| rowHeightProvider | function(row, key) | minimumRowHeight | 行高提供函数 |
| minimumRowHeight | int | 40 | 最小行高 |
| maximumRowHeight | int | Number.MAX_VALUE | 最大行高 |
| initModel | array | [] | 表格初始数据模型 |
| rowCount | int | 0 | 当前模型行数 |
| columns | array | [] | 列描述对象数组 |
| defaultCheckedKeys | array | [] | 默认选中的键列表 |
| checkedKeys | array | [] | 选中行的键列表 |
| colorGridLine | color | - | 网格线颜色 |
| showColumnHeader | bool | true | 是否显示列头 |
| columnHeaderTitleFont | font | - | 列头标题字体 |
| colorColumnHeaderTitle | color | - | 列头标题颜色 |
| colorColumnHeaderBg | color | - | 列头背景颜色 |
| showRowHeader | bool | true | 是否显示行头 |
| rowHeaderTitleFont | font | - | 行头标题字体 |
| colorRowHeaderTitle | color | - | 行头标题颜色 |
| colorRowHeaderBg | color | - | 行头背景颜色 |
| colorResizeBlockBg | color | - | 调整头大小块(左上角方块)背景色 |
| radiusBg | HusRadius | - | 背景圆角 |
| verScrollBar | HusScrollBar | - | 访问内部垂直滚动条 |
| horScrollBar | HusScrollBar | - | 访问内部水平滚动条 |
| tableView | TableView | - | 访问内部表格视图 |
| tableModel | TableModel | - | 访问内部表格模型 |
{initModel}支持的属性:
| 属性名 | 类型 | 可选/必选 | 描述 |
|---|---|---|---|
| key | string | 可选 | 本行数据键 |
| enabled | bool | 可选 | 本行是否禁用 |
{columns}支持的属性:
| 属性名 | 类型 | 可选/必选 | 描述 |
|---|---|---|---|
| title | string | 必选 | 标题 |
| dataIndex | string | 必选 | 数据索引 |
| delegate | var | 必选 | 该列的单元格代理 |
| width | int | 必选 | 该列初始宽度 |
| minimumWidth | int | 可选 | 该列最小宽度 |
| maximumWidth | int | 可选 | 该列最大宽度 |
| editable | bool | 可选 | 列头标题是否可编辑 |
| align | string | 可选 | 列头标题对齐方式, 支持 'center'丨'left'丨'right' |
| selectionType | string | 可选 | 该列选择类型, 支持 'checkbox'丨'radio' |
| sorter | var | 可选 | 该列排序器 |
| sortDirections | array | 可选 | 该列排序方向, 支持 'false'丨'ascend'丨'descend' |
| onFilter | var | 可选 | 该列过滤器 |
| filterInput | string | 可选 | 该列过滤输入 |
{columns.delegate}可访问属性:
| 属性名 | 类型 | 描述 |
|---|---|---|
| row | int | 行索引 |
| column | int | 列索引 |
| cellData | var | 单元格数据 |
| cellIndex | int | 单元格索引 |
| dataIndex | string | 数据索引 |
| filterInput | string | 单元格的过滤输入 |
支持的函数:
-
setColumnVisible(dataIndex: string, visible: bool)设置dataIndex对应列的可见为visible。 -
checkForRows(rows: Array)选中rows提供的行列表。 -
checkForKeys(keys: Array)选中keys提供的键列表。 -
toggleForRows(rows: Array)切换rows提供的行列表的选中状态。 -
toggleForKeys(keys: Array)切换keys提供的键列表的选中状态。 -
Array getCheckedKeys()获取选中的键列表。 -
clearAllCheckedKeys()清除所有选中的键。 -
scrollToRow(row: int)滚动到row指定的行。 -
sort(column: int)排序column指定的列(该列的描述对象需要具有sorter和sortDirections)。 -
clearSort()清除所有排序(即还原为初始状态)。 -
filter()使用提供的(如果有,可以多列)onFilter过滤整个模型,注意 此函数还会确定应用了排序的列并自动进行重排。 -
clearFilter()清除所有过滤(即还原为初始状态)。 -
clear()清空所有模型数据、排序和过滤。
注意 以下函数仅作用于当前(排序&过滤后)的数据,不会更改 initModel,并且,为了最佳的性能,
需要用户自行判断是否应该重新排序&过滤(调用 filter() 即可)
。
-
appendRow(object: var)在当前模型末尾添加object行, 不会更改initModel。 -
getRow(rowIndex: int): var获取当前模型rowIndex处的行数据。 -
setRow(rowIndex: int, object: var)设置当前模型rowIndex处行数据为object, 不会更改initModel。 -
insertRow(rowIndex: int, object: var)在当前模型插入行数据object到rowIndex处, 不会更改initModel。 -
moveRow(fromRowIndex: int, toRowIndex: int, count: int = 1)将count个模型数据从from位置移动到to位置, 不会更改initModel。 -
removeRow(rowIndex: int, count: int = 1)删除当前模型rowIndex处的count条行数据, 不会更改initModel。 -
getCellData(rowIndex: int, columnIndex: int): var获取当前模型(rowIndex, columnIndex)处的单元数据。 -
setCellData(rowIndex: int, columnIndex: int, data: var)设置当前模型(rowIndex, columnIndex)处的单元数据为data, 不会更改initModel。 -
getTableModel(): Array获取当前表格模型(排序&过滤后的数据)。 -
rowCount(): int获取当前模型的行数(排序&过滤后的数据)。 -
columnCount(): int获取当前模型的列数(排序&过滤后的数据)。
代码演示
示例 1 - 基本用法
简单的表格,最后一列是各种操作。
import QtQuick
import HuskarUI.Basic
Column {
width: parent.width
spacing: 10
HusTableView {
width: parent.width
height: 200
columns: [
{
title: 'Name',
dataIndex: 'name',
delegate: textDelegate,
width: 200
},
{
title: 'Age',
dataIndex: 'age',
delegate: textDelegate,
width: 100
},
{
title: 'Address',
dataIndex: 'address',
delegate: textDelegate,
width: 300
},
{
title: 'Tags',
dataIndex: 'tags',
delegate: tagsDelegate,
width: 200
},
{
title: 'Action',
dataIndex: 'action',
delegate: actionDelegate,
width: 300
}
]
initModel: [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
tags: ['nice', 'developer'],
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
tags: ['loser'],
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sydney No. 1 Lake Park',
tags: ['cool', 'teacher'],
}
]
}
}
示例 2 - 显示/隐藏指定行
通过 setColumnVisible(dataIndex: string, visible: bool) 来切换显示指定行。
import QtQuick
import HuskarUI.Basic
Column {
width: parent.width
spacing: 10
HusGroupBox {
title: 'Check to column visible'
padding: 20
Row {
spacing: 10
HusCheckBox { checked: true; text: 'Name'; onToggled: columnVisibleTable.setColumnVisible('name', checked); }
HusCheckBox { checked: true; text: 'Age'; onToggled: columnVisibleTable.setColumnVisible('age', checked); }
HusCheckBox { checked: true; text: 'Address'; onToggled: columnVisibleTable.setColumnVisible('address', checked); }
HusCheckBox { checked: true; text: 'Tags'; onToggled: columnVisibleTable.setColumnVisible('tags', checked); }
HusCheckBox { checked: true; text: 'Action'; onToggled: columnVisibleTable.setColumnVisible('action', checked); }
}
}
HusTableView {
id: columnVisibleTable
width: parent.width
height: 200
columns: [
{
title: 'Name',
dataIndex: 'name',
delegate: textDelegate,
width: 200
},
{
title: 'Age',
dataIndex: 'age',
delegate: textDelegate,
width: 100
},
{
title: 'Address',
dataIndex: 'address',
delegate: textDelegate,
width: 300
},
{
title: 'Tags',
dataIndex: 'tags',
delegate: tagsDelegate,
width: 200
},
{
title: 'Action',
dataIndex: 'action',
delegate: actionDelegate,
width: 300
}
]
initModel: [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
tags: ['nice', 'developer'],
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
tags: ['loser'],
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sydney No. 1 Lake Park',
tags: ['cool', 'teacher'],
}
]
}
}
示例 3 - 自定义选择项
通过 columns 对应列中的 selectionType 设置选择类型,目前支持 'checkbox' 多选框 / 'radio' 单选框。
注意 设置多列 selectionType 行为未定义。
通过 columns 对应列中的 editable 设置该列头是否可编辑。
通过 scrollToRow() 滚动到指定行。
通过 alternatingRow 设置是否交替显示行背景。
import QtQuick
import HuskarUI.Basic
Column {
width: parent.width
spacing: 10
Row {
spacing: 10
HusIconButton {
text: qsTr('Reload')
type: HusButton.Type_Primary
enabled: tableView.checkedKeys.length > 0
onClicked: {
loading = true;
reloadTimer.restart();
}
Timer {
id: reloadTimer
interval: 2000
onTriggered: {
parent.loading = false;
tableView.clearAllCheckedKeys();
}
}
}
HusButton {
text: qsTr('ScrollToRow 0')
type: HusButton.Type_Primary
onClicked: tableView.scrollToRow(0);
}
HusButton {
text: qsTr('ScrollToRow 99')
type: HusButton.Type_Primary
onClicked: tableView.scrollToRow(99);
}
HusCheckBox {
id: alternatingRowCheckBox
anchors.verticalCenter: parent.verticalCenter
text: qsTr('Switch alternatingRow')
}
}
HusTableView {
id: tableView
width: parent.width
height: 400
alternatingRow: alternatingRowCheckBox.checked
columns: [
{
title: 'Name',
dataIndex: 'name',
delegate: textDelegate,
width: 200,
minimumWidth: 100,
maximumWidth: 400,
align: 'center',
selectionType: 'checkbox',
},
{
title: 'Age',
dataIndex: 'age',
delegate: textDelegate,
width: 100,
editable: true,
},
{
title: 'Address',
dataIndex: 'address',
delegate: textDelegate,
width: 300
},
{
title: 'Tags',
dataIndex: 'tags',
delegate: tagsDelegate,
width: 350,
},
{
title: 'Action',
dataIndex: 'action',
delegate: actionDelegate,
width: 200
}
]
}
HusPagination {
anchors.horizontalCenter: parent.horizontalCenter
total: 1000
pageSize: 100
showQuickJumper: true
onCurrentPageIndexChanged: {
/*! 生成一些数据 */
tableView.initModel = Array.from({ length: pageSize }).map(
(_, i) => {
return {
key: String(i + currentPageIndex * pageSize),
name: `Edward King \${i + currentPageIndex * pageSize}`,
age: i % 30 + 30,
address: `London, Park Lane no. \${i + currentPageIndex * pageSize}`,
tags: ['nice', 'cool', 'loser', 'teacher', 'developer'].splice(0, i % 5 + 1),
}
});
}
}
HusTableView {
id: tableView2
width: parent.width
height: 400
alternatingRow: alternatingRowCheckBox.checked
columns: [
{
title: 'Name',
dataIndex: 'name',
delegate: textDelegate,
width: 200,
minimumWidth: 100,
maximumWidth: 400,
align: 'center',
selectionType: 'radio',
},
{
title: 'Age',
dataIndex: 'age',
delegate: textDelegate,
width: 100,
editable: true,
},
{
title: 'Address',
dataIndex: 'address',
delegate: textDelegate,
width: 300
},
{
title: 'Tags',
dataIndex: 'tags',
delegate: tagsDelegate,
width: 350,
},
{
title: 'Action',
dataIndex: 'action',
delegate: actionDelegate,
width: 200
}
]
}
HusPagination {
anchors.horizontalCenter: parent.horizontalCenter
total: 1000
pageSize: 100
showQuickJumper: true
onCurrentPageIndexChanged: {
/*! 生成一些数据 */
tableView2.initModel = Array.from({ length: pageSize }).map(
(_, i) => {
return {
key: String(i + currentPageIndex * pageSize),
name: `Edward King \${i + currentPageIndex * pageSize}`,
age: i % 30 + 30,
address: `London, Park Lane no. \${i + currentPageIndex * pageSize}`,
tags: ['nice', 'cool', 'loser', 'teacher', 'developer'].splice(0, i % 5 + 1),
}
});
}
}
}
示例 4 - 排序和过滤
通过 columns 对应列中的 sorter 设置排序器,其原型为 function(a, b){},具体可参考 Array.sort() 参数。
通过 columns 对应列中的 sortDirections 设置排序方向列表,在切换排序时按数组内容指示的方向依次切换,项 ascend 视作升序()。
通过 columns 对应列中的 onFilter 设置过滤器,其原型为 function(value, record){},value 为过滤输入,record 为当前数据记录。
一种在外部实现自定义过滤的方式
- 设置
columns对应列中的filterInput,接着调用filter()函数即可对该列实现过滤。
import QtQuick
import HuskarUI.Basic
Column {
width: parent.width
spacing: 10
HusTableView {
id: sortAndFilterTable
width: parent.width
height: 400
columns: [
{
title: 'Name',
dataIndex: 'name',
delegate: textDelegate,
width: 200,
minimumWidth: 100,
maximumWidth: 400,
align: 'center',
selectionType: 'checkbox',
},
{
title: 'Age',
dataIndex: 'age',
delegate: textDelegate,
width: 150,
sorter: (a, b) => a.age - b.age,
sortDirections: ['descend', 'false'],
onFilter: (value, record) => String(record.age).includes(value)
},
{
title: 'Address',
dataIndex: 'address',
delegate: textDelegate,
width: 300,
sorter: (a, b) => a.address.length - b.address.length,
sortDirections: ['ascend', 'descend', 'false'],
onFilter: (value, record) => record.address.includes(value)
},
{
title: 'Tags',
dataIndex: 'tags',
delegate: tagsDelegate,
width: 350,
},
]
}
HusPagination {
anchors.horizontalCenter: parent.horizontalCenter
total: 1000
pageSize: 100
showQuickJumper: true
onCurrentPageIndexChanged: {
/*! 生成一些数据 */
sortAndFilterTable.initModel = Array.from({ length: pageSize }).map(
(_, i) => {
return {
key: String(i + currentPageIndex * pageSize),
name: `Edward King \${i + currentPageIndex * pageSize}`,
age: i % 30 + 30,
address: `London, Park Lane no. \${i + currentPageIndex * pageSize}`,
tags: ['nice', 'cool', 'loser', 'teacher', 'developer'].splice(0, i % 5 + 1),
}
});
}
}
}
示例 5 - 从C++中导入数据
通常来说,大多数人从 C++ 创建和处理数据。
有一种相当简单的方式将数据从 C++ 导入到 Qml 环境:
- 使用 QVariant 包装你的数据结构。
struct MyData {
QString name;
int age;
QVariantMap toVariant() {
QVariantMap var;
var["name"] = name;
var["age"] = age;
return var;
}
};
- 提供访问你的数据集接口,类型可以是 QVariant/QVariantList/QVariantMap。
Q_INVOKABLE QVariantList getMyDataList() {
MyData myData;
QVariantList list;
list.append(data.toVariant());
return list;
}
- 在 Qml 中直接访问该数据集并赋值给 HusTableView.initModel。
HusTableView {
Component.onCompleted: {
initModel = getMyDataList();
}
}
- 注意 使用 HusTableView 提供的接口操作数据(增删查改)。
更详细的说明请参考官方文档:
import QtQuick
import HuskarUI.Basic
import Gallery
Column {
spacing: 10
width: parent.width
HusButton {
text: qsTr('Import 10 pieces data from C++')
type: HusButton.Type_Primary
onClicked: {
const list = DataGenerator.genTableData(10);
for (const object of list) {
cppTableView.appendRow(object);
}
}
}
HusTableView {
id: cppTableView
width: parent.width
height: 400
columns: [
{
title: 'Name',
dataIndex: 'name',
delegate: textDelegate,
width: 200
},
{
title: 'Age',
dataIndex: 'age',
delegate: textDelegate,
width: 100
},
{
title: 'Address',
dataIndex: 'address',
delegate: textDelegate,
width: 300
},
{
title: 'Tags',
dataIndex: 'tags',
delegate: tagsDelegate,
width: 200
},
{
title: 'Action',
dataIndex: 'action',
delegate: actionDelegate,
width: 300
}
]
Component.onCompleted: {
initModel = DataGenerator.genTableData(10);
}
}
}