TableView QML 类型
提供显示从模型中获取数据的表格视图。 更多...
属性
- alternatingRows : bool
- animate : bool
(自 6.4)
- bottomRow : int
- columnSpacing : real
- columnWidthProvider : var
- columns : int
- contentHeight : real
- contentWidth : real
- currentColumn : int
- currentRow : int
- delegate : Component
- editTriggers : enumeration
(自 6.5)
- keyNavigationEnabled : bool
(自 6.4)
- leftColumn : int
- model : model
- pointerNavigationEnabled : bool
(自 6.4)
- resizableColumns : bool
(自 6.5)
- resizableRows : bool
(自 6.5)
- reuseItems : bool
- rightColumn : int
- rowHeightProvider : var
- rowSpacing : real
- rows : int
- selectionBehavior : enumeration
(自 6.4)
- selectionMode : enumeration
(自 6.6)
- selectionModel : ItemSelectionModel
(自 6.2)
- syncDirection : Qt::Orientations
- syncView : TableView
- topRow : int
附加属性
- editDelegate : 组件
- view : 表视图
信号
- layoutChanged()
(自 6.5)
附加信号
方法
- point cellAtIndex(QModelIndex modelIndex)
(自 6.4)
- Point cellAtPosition(point position, bool includeSpacing)
- Point cellAtPosition(real x, real y, bool includeSpacing)
- clearColumnWidths()
- clearRowHeights()
- closeEditor()
(自 6.5)
- int columnAtIndex(QModelIndex modelIndex)
(自 6.4)
- real columnWidth(int column)
(自 6.2)
- edit(QModelIndex modelIndex)
(自 6.5)
- qreal explicitColumnWidth(int column)
- qreal explicitRowHeight(int row)
- forceLayout()
- real implicitColumnWidth(int column)
(自 6.2)
- real implicitRowHeight(int row)
(自 6.2)
- QModelIndex index(int row, int column)
(自 6.4.3)
- bool isColumnLoaded(int column)
(自 6.2)
- bool isRowLoaded(int row)
(自 6.2)
- Item itemAtCell(point cell)
- Item itemAtIndex(QModelIndex index)
(自 6.5)
- QModelIndex modelIndex(point cell)
(自 6.4)
- positionViewAtCell(point cell, PositionMode mode, point offset, rect subRect)
- positionViewAtColumn(int column, PositionMode mode, real offset, rect subRect)
- positionViewAtIndex(QModelIndex index, PositionMode mode, point offset, rect subRect)
(自 6.5)
- positionViewAtRow(int row, PositionMode mode, real offset, rect subRect)
- int rowAtIndex(QModelIndex modelIndex)
(自 6.4)
- real rowHeight(int row)
(自 6.2)
- setColumnWidth(int column, real size)
- setRowHeight(int row, real size)
详细描述
TableView 具有定义要显示的数据的 model 和定义数据应如何显示的 delegate。
TableView 继承自 Flickable。这意味着虽然模型可以具有任意数量的行和列,但通常只会在视口中显示表格的子部分。一旦你滑动,新的行和列就会进入视口,而旧的行和列则退出并从视口中移除。移出行和列会被重新利用来构建进入视口的行和列。因此,TableView 支持任何大小的模型而不会影响性能。
TableView 用于显示由内置 QML 类型(如 ListModel 和 XmlListModel)创建的模型,这些类型仅在TableView的第一列填充数据。要创建具有多列的模型,请使用 TableModel 或继承自 QAbstractItemModel 的 C++ 模型。
TableView 默认不包含标题。您可以使用 Qt Quick Controls 中的 HorizontalHeaderView 和 VerticalHeaderView 添加标题。
注意:TableView 只加载所需填充视口的委托项目数量。无法保证加载视口外的项目,尽管TableView有时会为了优化而预加载项目。因此,宽度或高度为零的TableView可能根本不会加载任何委托项目。
示例用法
C++ 模型
以下示例展示了如何使用 C++ 创建多列模型
#include <qqml.h> #include <QAbstractTableModel> class TableModel : public QAbstractTableModel { Q_OBJECT QML_ELEMENT QML_ADDED_IN_VERSION(1, 1) public: int rowCount(const QModelIndex & = QModelIndex()) const override { return 200; } int columnCount(const QModelIndex & = QModelIndex()) const override { return 200; } QVariant data(const QModelIndex &index, int role) const override { switch (role) { case Qt::DisplayRole: return QString("%1, %2").arg(index.column()).arg(index.row()); default: break; } return QVariant(); } QHash<int, QByteArray> roleNames() const override { return { {Qt::DisplayRole, "display"} }; } };
然后从 QML 中如何使用它
import QtQuick import TableModel 0.1 TableView { anchors.fill: parent columnSpacing: 1 rowSpacing: 1 clip: true model: TableModel {} delegate: Rectangle { implicitWidth: 100 implicitHeight: 50 Text { text: display } } }
QML 模型
对于原型设计和显示非常简单的数据(例如,从网络 API),可以使用 TableModel。
import QtQuick import Qt.labs.qmlmodels TableView { anchors.fill: parent columnSpacing: 1 rowSpacing: 1 clip: true model: TableModel { TableModelColumn { display: "name" } TableModelColumn { display: "color" } rows: [ { "name": "cat", "color": "black" }, { "name": "dog", "color": "brown" }, { "name": "bird", "color": "white" } ] } delegate: Rectangle { implicitWidth: 100 implicitHeight: 50 border.width: 1 Text { text: display anchors.centerIn: parent } } }
重用项目
TableView 默认通过重用委托项目来回收利用,而不是每次将新的行和列滑动到视口中时都从 delegate 中实例化。这种方法可以根据委托的复杂性带来巨大的性能提升。
当项目被滑动出去时,它会移动到 重用池,这是一个未使用的项目内部缓存。当发生这种情况时,会发出 TableView::pooled 信号来通知项目。类似地,当项目从池中移回时,会发出 TableView::reused 信号。
在项目重用时会更新从模型来的任何项目属性。这包括 index
、row
和 column
,以及任何模型角色。
注意:避免在委托内存储任何状态。如果您这样做,则在收到 TableView::reused 信号时手动重置它。
如果您有计时器或动画的项目,请在收到 TableView::pooled 信号时暂停它们。这样,您可以避免为不可见的项目使用 CPU 资源。同样,如果项目中有无法重用的资源,您可以将其释放。
如果您不想重用项目或如果 delegate 不支持重用,您可以设置 reuseItems 属性为 false
。
注意:在项目处于池中时,项目可能仍然处于活动状态并响应连接的信号和绑定。
以下示例显示了一个动画旋转矩形的委托。当它被放入池中时,动画临时暂停
Component { id: tableViewDelegate Rectangle { implicitWidth: 100 implicitHeight: 50 TableView.onPooled: rotationAnimation.pause() TableView.onReused: rotationAnimation.resume() Rectangle { id: rect anchors.centerIn: parent width: 40 height: 5 color: "green" RotationAnimation { id: rotationAnimation target: rect duration: (Math.random() * 2000) + 200 from: 0 to: 359 running: true loops: Animation.Infinite } } } }
行高和列宽
当一个新的列被滑动到视图中时,TableView将调用columnWidthProvider来确定其宽度。如果已设置,则此函数将独立决定列的宽度。否则,它将检查是否使用了setColumnWidth()设置了明确的宽度。如果没有,将使用implicitColumnWidth()。列的隐式宽度是当前在该列中加载的代理项中找到的最大隐式宽度。直接在一个代理项上设置显式width
将没有效果,并且将被忽略并覆盖。相同的逻辑也适用于行高。
等效于默认逻辑的columnWidthProvider实现可能会是:
columnWidthProvider: function(column) { let w = explicitColumnWidth(column) if (w >= 0) return w; return implicitColumnWidth(column) }
一旦列宽度得到解决,同一列中的所有其他项目都会调整为这个宽度,包括稍后滑动到视图中该项目。
注意:当整个列被滑动出视图时,列的解决宽度将被丢弃,并且当它被再次滑动进来时将被重新计算。这意味着如果宽度依赖于implicitColumnWidth,则每次计算的值可能都不同,这取决于列进入时的哪一行(因为implicitColumnWidth()只考虑当前加载的代理项)。为了避免这种情况,您应使用columnWidthProvider,或者确保同一列中的所有代理项都具有相同的implicitWidth
。
如果您更改rowHeightProvider或columnWidthProvider为视口内部的行和列返回的值,您必须调用forceLayout。这会通知TableView它需要再次使用提供者函数来重新计算和更新布局。
从Qt 5.13开始,如果您想隐藏特定列,可以从该列的columnWidthProvider返回0
。同样,您可以从不返回rowHeightProvider返回的值隐藏一行。如果您返回负数,TableView将回退到根据代理项计算大小。
注意:行或列的大小应该是整数,以避免项目的亚像素对齐。
以下示例演示了如何设置一个简单的columnWidthProvider
,同时还带有一个修改函数返回值的计时器。当数组被修改时,forceLayout会被调用以使更改生效
TableView { id: tableView property var columnWidths: [100, 50, 80, 150] columnWidthProvider: function (column) { return columnWidths[column] } Timer { running: true interval: 2000 onTriggered: { tableView.columnWidths[2] = 150 tableView.forceLayout(); } } }
编辑单元格
您可以通过提供编辑代理来允许用户编辑表格单元格。编辑代理将根据editTriggers来实例化,默认情况下是当用户双击单元格或按下例如Qt::Key_Enter或Qt::Key_Return。通过在delegate上设置TableView::editDelegate来设置编辑代理,这是一个您设置的附加属性。以下代码片段演示了如何做到这一点
TableView { id: tableView anchors.fill: parent clip: true model: TableModel { TableModelColumn { display: "name" } rows: [ { "name": "Harry" }, { "name": "Hedwig" } ] } selectionModel: ItemSelectionModel {} delegate: Rectangle { implicitWidth: 100 implicitHeight: 50 Text { anchors.centerIn: parent text: display } TableView.editDelegate: TextField { anchors.fill: parent text: display horizontalAlignment: TextInput.AlignHCenter verticalAlignment: TextInput.AlignVCenter Component.onCompleted: selectAll() TableView.onCommit: { display = text // 'display = text' is short-hand for: // let index = TableView.view.index(row, column) // TableView.view.model.setData(index, text, Qt.DisplayRole) } } } }
如果用户在编辑代理激活时按下Qt::Key_Enter 或 Qt::Key_Return,TableView 将向编辑代理发送 TableView::commit 信号,以便它可以将更改后的数据写回模型。
注意: 为了使单元格可编辑,模型需要重写 QAbstractItemModel::flags(),并返回 Qt::ItemIsEditable
。默认情况下,在 QAbstractItemModel 中不会启用此标志。重写示例可能如下所示:
Qt::ItemFlags QAbstractItemModelSubClass::flags(const QModelIndex &index) const override { Q_UNUSED(index) return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; }
如果 TableView 代理 定义了名为 required property bool editing
的属性,则正在编辑的代理将被设置为 true
。有关如何使用的示例,请参阅 editDelegate 的文档。
覆盖和叠加
从代理实例化的所有新项目都是作为具有 z
值 1
的 contentItem 的父项。您可以在 Tableview 中添加自己的项目,作为 Flickable 的子项。通过控制它们的 z
值,您可以使它们在表格条目之上或之下。
以下示例显示了如何添加一些文本到表格上方,当您滑动时,这些文本会一起移动。
TableView { id: tableView topMargin: header.implicitHeight Text { id: header text: "A table header" } }
以下示例显示了如何创建一个叠加项目,该项目始终位于特定单元格之上。由于用户(例如,在它前面调整列大小时),单元格的位置会改变,因此这需要更多代码。
Rectangle { id: overlay width: 20 height: 20 radius: 10 color: "blue" z: 10 parent: tableView.contentItem Connections { target: tableView function onLayoutChanged() { let item = tableView.itemAtCell(5, 5) let insideViewport = item !== null overlay.visible = insideViewport if (insideViewport) { overlay.x = item.x overlay.y = item.y } } } }
您也可以直接将叠加项目作为单元格的子项,而不是作为 contentItem。但是这样做可能会很脆弱,因为当单元格从视图中滚动出去时,它将被卸载或重新使用。
项目选择
您可以通过将 ItemSelectionModel 分配给 selectionModel 属性来为 TableView 添加选择支持。然后它将使用此模型来控制哪些委托项目应显示为选中,哪些项目应显示为当前。您可以将 selectionBehavior 设置为控制用户是否允许选择单个单元格、行或列。
要确定委托是否选中或当前,请声明以下属性
注意: 必须将 selected
和 current
属性定义为 required
。这将通知 TableView 它应负责更新它们的值。如果不这样做,它们将简单地被忽略。有关更多信息,请参阅Required Properties。
以下代码片段显示了应用程序如何根据 selected
属性渲染不同的委托。
TableView { id: tableView anchors.fill: parent clip: true model: TableModel { TableModelColumn { display: "name" } rows: [ { "name": "Harry" }, { "name": "Hedwig" } ] } selectionModel: ItemSelectionModel {} delegate: Rectangle { implicitWidth: 100 implicitHeight: 30 color: selected ? "blue" : "lightgray" required property bool selected Text { text: display } } }
如果需要根据当前项目所在的行或列的不同位置渲染委托,则 currentRow 和 currentColumn 属性也可能很有用。
注意: Qt Quick Controls 提供了一个 SelectionRectangle,可以用来让用户选择单元格。
注意: 默认情况下,当用户在单元格上轻触时,单元格将成为 current,并且任何选择都将被清除。如果您不想使用这种默认的轻触行为(例如,如果您在委托内部使用自定义指针处理程序),则可以将 pointerNavigationEnabled 设置为 false
。
键盘导航[1]
为了支持键盘导航,您需要将ItemSelectionModel分配给selectionModel属性。然后TableView将使用此模型来操作模型的currentIndex。
将自身渲染为当前是代理的责任。您可以通过向它添加一个属性required property bool current
来这样做,并让外观取决于其状态。TableView将设置current
属性值。您还可以通过将keyNavigationEnabled设置为false
来完全禁用键盘导航(如果您想实现自己的按键处理程序)。
以下示例演示了如何使用键盘导航以及current
和selected
属性
ApplicationWindow { width: 800 height: 600 visible: true ScrollView { anchors.fill: parent TableView { id: tableView clip: true interactive: true rowSpacing: 1 columnSpacing: 1 model: TableModel { TableModelColumn { display: "checked" } TableModelColumn { display: "amount" } TableModelColumn { display: "fruitType" } TableModelColumn { display: "fruitName" } TableModelColumn { display: "fruitPrice" } rows: [ { checked: false, amount: 1, fruitType: "Apple", fruitName: "Granny Smith", fruitPrice: 1.50 }, { checked: true, amount: 4, fruitType: "Orange", fruitName: "Navel", fruitPrice: 2.50 }, { checked: false, amount: 1, fruitType: "Banana", fruitName: "Cavendish", fruitPrice: 3.50 } ] } selectionModel: ItemSelectionModel {} delegate: Rectangle { implicitWidth: 100 implicitHeight: 50 required property bool selected required property bool current border.width: current ? 2 : 0 color: selected ? "lightblue" : palette.base Text{ text: model.display padding: 12 } } } } SelectionRectangle { target: tableView } }
复制和粘贴[2]
为TableView实现复制和粘贴操作通常也包括使用一个QUndoStack(或任何其他的撤销/重做框架)。可以使用QUndoStack来存储对模型执行的不同操作,例如添加或删除行,或从剪贴板粘贴数据,并提供一种方法来稍后撤销它们。然而,一个描述可能操作及其如何撤销的QUndoStack应根据模型和应用程序的需求来设计。因此,TableView不提供内置API处理复制和粘贴。
以下代码片段可以用作将复制和粘贴支持添加到您的模型和TableView的参考。它使用了QAbstractItemModel中现有的mimedata API,以及QClipboard。这个代码片段按原样工作,但也可扩展以使用QUndoStack。
// Inside your C++ QAbstractTableModel subclass: Q_INVOKABLE void copyToClipboard(const QModelIndexList &indexes) const { QGuiApplication::clipboard()->setMimeData(mimeData(indexes)); } Q_INVOKABLE bool pasteFromClipboard(const QModelIndex &targetIndex) { const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(); // Consider using a QUndoCommand for the following call. It should store // the (mime) data for the model items that are about to be overwritten, so // that a later call to undo can revert it. return dropMimeData(mimeData, Qt::CopyAction, -1, -1, targetIndex); }
这两个函数可以从QML使用如下
TableView { id: tableView model: tableModel selectionModel: ItemSelectionModel {} Shortcut { sequence: StandardKey.Copy onActivated: { let indexes = tableView.selectionModel.selectedIndexes tableView.model.copyToClipboard(indexes) } } Shortcut { sequence: StandardKey.Paste onActivated: { let targetIndex = tableView.selectionModel.currentIndex tableView.model.pasteFromClipboard(targetIndex) } } }
另请参阅TableView::editDelegate、TableView::commit、editTriggers、edit()、closeEditor()、layoutChanged()、QAbstractItemModel::mimeData、QAbstractItemModel::dropMimeData、QUndoStack、QUndoCommand和QClipboard。
属性文档
alternatingRows : bool |
此属性控制行的背景颜色是否应当交替。默认值取决于风格。
注意:此属性仅作为提示,因此可能会被自定义代理忽略。建议当此提示为true
时,委托在palette.base
和palette.alternateBase
之间交替,以便可以从外部设置颜色。例如
background: Rectangle { color: control.row === control.tableView.currentRow ? control.palette.highlight : (control.tableView.alternatingRows && control.row % 2 !== 0 ? control.palette.alternateBase : control.palette.base) }
animate : bool |
可以将该属性设置为控制如果TableView应当动画化contentItem(contentX和contentY)。它被positionViewAtCell()使用,并在使用键盘导航当前索引时。默认值是true
。
如果设置为false
,任何正在进行的动画将立即停止。
注意: 该属性仅作为提示。在例如目标单元格未加载的情况下,TableView可能会选择在没有任何动画的情况下定位内容项。然而,如果设置为false
,动画将始终关闭。
此属性自Qt 6.4版本引入。
另请参阅 positionViewAtCell()。
bottomRow : int |
此属性保留当前在视图内部可见的最后一行。
另请参阅 leftColumn、rightColumn和topRow。
columnSpacing : real |
此属性保留列之间的间距。
默认值为0
。
columnWidthProvider : var |
此属性可以保留一个函数,该函数返回模型中每一列的列宽。当TableView
需要知道特定列的宽度时,会调用该函数。该函数接收一个参数column
,对于该参数TableView
需要知道宽度。
自Qt 5.13起,如果您想隐藏特定列,可以为该列返回0
宽度。如果您返回一个负数,TableView
将根据代理项目计算宽度。
注意: 当列即将加载(或进行布局)时,通常会调用columnWidthProvider两次。第一次,以了解列是否可见并且需要加载。第二次,确定所有项目加载后列的宽度。如果您需要根据代理项目的尺寸计算列宽,则需要等待第二次调用,即所有项目都加载完毕。您可以通过调用isColumnLoaded(column)来检查此情况,如果尚未完成,则简单返回-1。
另请参阅 rowHeightProvider、isColumnLoaded()和行高和列宽。
columns : int |
此属性保留表中的列数。
注意: columns通常等于模型中的列数,但在处理所有挂起模型更改之前可能会暂时不同。
如果模型是列表,列数将等于1
。
此属性为只读。
contentHeight : real |
此属性保留用于容纳数据模型中行数的表格高度。这通常不等于view
的height
,这意味着表格的高度可能大于或小于视口高度。由于TableView
无法始终知道表格的确切高度而不加载数据模型中的所有行,因此contentHeight
通常是基于最初加载的表格的估计。
如果您知道表格的高度,将一个值赋给contentHeight
以避免不必要的计算和TableView
的更新。
contentWidth : 实数 |
此属性保存了模型的列数所需的表宽度。这通常与视图的 宽度
不同,这意味着表的宽度可能大于或小于视口宽度。由于 TableView 无法在没有加载所有列的情况下总是知道表的准确宽度,因此通常 contentWidth
是基于最初加载的表进行估算。
如果您知道表的宽度,则将值分配给 contentWidth
,以避免不必要的计算和 TableView 的更新。
另请参阅contentHeight 和 columnWidthProvider。
currentColumn : 整数 |
此只读属性保存包含当前项的视图中的列。如果没有当前项,则将 -1
。
注意:为了使 TableView 报告当前列,您需要将 ItemSelectionModel 分配给 selectionModel。
另请参阅currentRow,selectionModel 和 选择项。
currentRow : 整数 |
此只读属性保存包含当前项的视图中的行。如果没有当前项,则将 -1
。
注意:为了使 TableView 报告当前行,您需要将 ItemSelectionModel 分配给 selectionModel。
另请参阅currentColumn,selectionModel 和 选择项。
delegate : 组件 |
代理提供定义视图实例化的每个单元格项的模板。模型索引作为可访问的 index
属性公开。同样适用于 row
和 column
。根据 数据模型 的类型,模型属性也可用。
代理应使用 implicitWidth 和 implicitHeight 指定其大小。TableView 将根据该信息布局项。显式宽度和高度设置被忽略并覆盖。
在代理内部,您可以可选地添加一个或多个以下属性。TableView 会修改这些属性值,以通知代理其状态。这可以被代理用来根据其自身状态以不同的方式渲染。
- 必需属性 bool current - 如果委托是 当前项,则为
true
。 - 必需属性 bool selected - 如果委托是 选择项,则为
true
。 - 必需属性 bool editing -
true
如果委托正在被 编辑。
以下示例展示了如何使用这些属性
delegate: Rectangle { required property bool current required property bool selected border.width: current ? 1 : 0 color: selected ? palette.highlight : palette.base }
注意:委托按需实例化,可能在任何时候被销毁。如果设置了 reuseItems 属性为 true
则还会被复用。因此,你应该避免在委托中存储状态信息。
editTriggers : 枚举 |
该属性持有用户开始编辑单元格的不同方式。它可以是由以下值组成的组合
常量 | 描述 |
---|---|
TableView.NoEditTriggers | - 用户不能触发单元格的编辑。当设置此值时,TableView 将不会对任何用户交互响应打开或关闭编辑委托。但应用程序可以手动调用 edit() 和 closeEditor()。 |
TableView.SingleTapped | - 用户可以通过单次点击来编辑单元格。 |
TableView.DoubleTapped | - 用户可以通过双击来编辑单元格。 |
TableView.SelectedTapped | - 用户可以通过点击来编辑 已选单元格。 |
TableView.EditKeyPressed | - 用户可以通过按下一个编辑键来编辑 当前单元格。编辑键由操作系统决定,但通常是 Qt::Key_Enter 和 Qt::Key_Return 。 |
TableView.AnyKeyPressed | - 用户可以通过按下任何键(不是单元格导航键)来编辑 当前单元格。按下的键也发送到 edit delegate 内部的焦点对象。 |
要使 TableView.SelectedTapped
, TableView.EditKeyPressed
和 TableView.AnyKeyPressed
起作用,TableView 需要有分配的 selection model,因为它们依赖于一个 当前索引 被设置。要能够接收所有的按键事件,TableView 还需要有 QQuickItem::activeFocus。
在编辑单元格时,用户可以按 Qt::Key_Tab
或 Qt::Key_Backtab
来发送数据并移动到下一个单元格进行编辑。此行为可以通过将 QQuickItem::activeFocusOnTab 在 TableView 上设置为 false
来禁用。
注意:为了使单元格可编辑,delegate 需要一个附加的 edit delegate,模型需要从 QAbstractItemModel::flags() 返回 Qt::ItemIsEditable
(示例在下文)。如果无法在激活指定的触发器后编辑单元格,你可以尝试显式调用 edit() 作为帮助(例如从 Button/TapHandler)。这样做将打印出警告,说明为什么单元格无法编辑。
Qt::ItemFlags QAbstractItemModelSubClass::flags(const QModelIndex &index) const override { Q_UNUSED(index) return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; }
该属性是在 Qt 6.5 中引入的。
keyNavigationEnabled : bool |
此属性可以设置以控制用户是否能够使用键盘更改 当前索引。默认值是 true
。
注意:要使 TableView 支持键盘导航,您需要将 ItemSelectionModel 分配给 selectionModel。
此属性自Qt 6.4版本引入。
另请参阅 键盘导航、selectionModel、selectionBehavior、pointerNavigationEnabled 和 interactive。
leftColumn : int |
此属性保留当前在视图中可见的最左侧列。
另请参阅 rightColumn、topRow 和 bottomRow。
model : model |
此属性保留提供表格数据的数据模型。
模型提供用于在视图中创建项的数据集。模型可以直接在 QML 中使用 TableModel、ListModel、ObjectModel 或通过自定义 C++ 模型类提供。C++ 模型必须是 QAbstractItemModel 或简单列表的子类。
另请参阅 数据模型。
pointerNavigationEnabled : bool |
此属性可以设置以控制用户是否能够使用鼠标或触摸更改 当前索引。默认值是 true
。
此属性自Qt 6.4版本引入。
resizableColumns : bool |
此属性保留是否允许用户通过在单元格之间拖动来调整列的大小。默认值是 false
。
该属性是在 Qt 6.5 中引入的。
resizableRows : bool |
此属性保留是否允许用户通过在单元格之间拖动来调整行的大小。默认值是 false
。
该属性是在 Qt 6.5 中引入的。
reuseItems : bool |
此属性保留是否应重用从 delegate 实例化的项。如果设置为 false
,则销毁任何当前池中的项。
另请参阅 重用项、TableView::pooled 和 TableView::reused。
rightColumn : int |
此属性保留当前在视图中可见的最右侧列。
另请参阅 左侧列leftColumn、顶部行topRow 和 底部行bottomRow。
rowHeightProvider : var |
此属性可以保存一个函数,该函数返回模型中每一行的行高。每当 TableView 需要知道特定行的高度时,都会调用该函数。该函数接受一个参数,row
,对于该参数,TableView 需要知道其高度。
从 Qt 5.13 开始,如果您想隐藏特定行,可以为该行返回 0
高度。如果返回负数,TableView 将基于代理项计算高度。
注意:rowHeightProvider 在行即将加载(或在布局时)通常会被调用两次。第一次是为了知道行是否可见以及是否应该被加载。第二次是在所有项目都已加载后确定行的高度。如果您需要根据代理项的大小计算行高,需要等待第二次调用,当所有项目都已加载。您可以通过调用 isRowLoaded(row) 来检查此情况,如果尚未如此,则简单地返回 -1。
另请参阅:rowHeightProvider、isRowLoaded() 和 行高和列宽。
rowSpacing : real |
此属性保存行之间的间距。
默认值为0
。
rows : int |
此属性保存表中的行数。
注意:rows 通常等于模型中的行数,但在所有挂起的模型更改都已被处理之前可能会暂时不同。
此属性为只读。
selectionBehavior : enumeration |
此属性保存用户是否可以选中单元格、行或列。
常量 | 描述 |
---|---|
TableView.SelectionDisabled | 用户不能执行选择操作 |
TableView.SelectCells | (默认值) 用户可以选中单个单元格 |
TableView.SelectRows | 用户只能选择行 |
TableView.SelectColumns | 用户只能选择列 |
此属性自Qt 6.4版本引入。
另请参阅:选择项目Selecting items、selectionMode 属性selectionMode、selectionModel 属性selectionModel 和 keyNavigationEnabled 属性keyNavigationEnabled。
selectionMode : enumeration |
如果 selectionBehavior 设置为 TableView.SelectCells,此属性保存用户是否可以一次选择一个单元格,或选择多个单元格。如果 selectionBehavior 设置为 TableView.SelectRows,此属性保存用户是否可以一次选择一行,或选择多行。如果 selectionBehavior 设置为 TableView.SelectColumns,此属性保存用户是否可以一次选择一列,或选择多列。
以下模式可用
常量 | 描述 |
---|---|
TableView.SingleSelection | 用户可以选中单个单元格、行或列。 |
TableView.ContiguousSelection | 用户可以选择单个连续的单元格块。在拖动选择的同时按住 Shift 键可以增加或减小现有选择的范围。 |
TableView.ExtendedSelection | (默认值)用户可以选择多个单独的单元格块。在拖动选择的同时按住 Shift 键可以增加或减小现有选择的范围。按住 Control 键同时拖动可以选择新的选择块,而不会清除当前选择。 |
该属性自 Qt 6.6 版本开始引入。
另请参阅 选择项目,selectionBehavior,selectionModel 和 keyNavigationEnabled。
selectionModel : ItemSelectionModel |
该属性可以设置来控制应显示哪些委托项作为已选中项,以及哪个项应显示为当前项。如果委托定义了 required property bool selected
,则 TableView 会将其与其在 TableView 中的所选模型项的选中状态保持同步。如果委托定义了 required property bool current
,则 TableView 会将其与 TableView 的 currentIndex
保持同步。
该属性自 Qt 6.2 版本开始引入。
另请参阅 选择项目,SelectionRectangle,keyNavigationEnabled 和 pointerNavigationEnabled。
syncDirection : Qt::Orientations |
syncView : TableView |
如果将此属性的 TableView 设置为另一个 TableView,则两个表格将在滑动、列宽/行高和间距方面根据 syncDirection 进行同步。
如果 syncDirection 包含 Qt.Horizontal,则当前 TableView 的列宽、列间距和水平滑动动作与 TableView 的同步视图同步。
如果 syncDirection 包含 Qt.Vertical,则当前 TableView 的行高、行间距和垂直滑动动作与 TableView 的同步视图同步。
另请参阅 syncDirection。
topRow : int |
该属性保留在当前视图中可见的最顶部行。
另请参阅 leftColumn、rightColumn 以及 bottomRow。
附加属性文档
TableView.editDelegate : 组件 |
此附加属性包含编辑代理。在开始编辑时进行实例化,并将其赋予所编辑的代理。它支持像 TableView 代理 一样的必需属性,包括 index
、row
和 column
。根据模型公开的 角色名称,也提供了模型属性,例如 display
和 edit
。
当满足由 editTriggers 指定的操作,并且当前单元格可编辑时,开始编辑。
注意:为了使单元格可编辑,模型需要重写 QAbstractItemModel::flags() 并返回 Qt::ItemIsEditable
。
您还可以通过调用 edit() 和 closeEditor() 分别手动打开和关闭编辑代理。然后,将忽略 Qt::ItemIsEditable
标志。
当用户按下 Qt::Key_Enter
或 Qt::Key_Return
(如果 TableView 设置了 QQuickItem::activeFocusOnTab,则还包括 Qt::Key_Tab
或 Qt::Key_Backtab
)时,编辑结束。在这种情况下,将发出 TableView::commit 信号,以便编辑代理可以响应并提交更改。如果由于其他原因结束编辑(例如,如果用户按下 Qt::Key_Escape),则不会发出信号。在任何情况下,最终都会发出 destruction() 信号。
在编辑代理显示时,其下方的单元格仍然可见,因此如果编辑代理是半透明的,或没有覆盖整个单元格,它会显得透明。如果不希望这样,可以有两种方法:让编辑代理的根元素是一个实心的 矩形,或者隐藏 TableView 代理 中的部分元素。这可以通过在其中定义一个属性 required property bool editing
来完成,并将其绑定到某些子元素的 visible 属性上。以下片段显示了如何实现这一点:
delegate: Rectangle { implicitWidth: 100 implicitHeight: 50 required property bool editing Text { id: textField anchors.fill: parent anchors.margins: 5 text: display visible: !editing } TableView.editDelegate: TextField { x: textField.x y: textField.y width: textField.width height: textField.height text: display TableView.onCommit: display = text } }
当编辑代理实例化时,TableView 将调用 QQuickItem::forceActiveFocus()。如果您想将活动焦点设置在编辑代理的某个子元素上,可以将编辑代理设置为 FocusScope。
另请参阅 editTriggers、TableView::commit、edit()、closeEditor() 以及 编辑单元格。
TableView.view : TableView |
此附加属性包含管理代理实例的视图。它附加到每个代理实例。
信号文档
|
每当加载的行和列的布局可能发生变化时,都会发出此信号。特别是在调用 forceLayout() 时,以及调整行或列大小,或者行或列进入或离开视图区域时,都会发生这种情况。
此信号可用于更新覆盖图的几何形状等。
注意:相应的事件处理器是 onLayoutChanged
。
此信号是在 Qt 6.5 中引入的。
另请参阅:forceLayout() 和 覆盖和底图。
附加信号文档
commit() |
此信号由 编辑代理发出。
当 编辑代理活动时,并且用户按下 Qt::Key_Enter 或 Qt::Key_Return 时,会发出此附加信号。如果 TableView 设置了 QQuickItem::activeFocusOnTab,并且用户按下 Qt::Key_Tab 或 Qt::Key_Backtab,同样会发出此信号。
如果由于除上述之外的原因结束编辑,将不会发出此信号。例如,如果用户按下 Qt::Key_Escape,在代理外轻触,正在编辑的行或列被删除,或应用程序调用 closeEditor()。
收到此信号后,编辑代理应将任何更改后的数据写回模型。
注意:相应的事件处理器是 onCommit
。
另请参阅:TableView::editDelegate、editTriggers 和 编辑单元格。
pooled() |
此信号在项目被添加到重用池之后发出。您可以使用它来暂停项目内的计时器或动画,或者释放无法重用的资源。
只有当 reuseItems 属性设置为 true
时,才会发出此信号。
注意:相应的事件处理器是 onPooled
。
另请参阅:重用项、reuseItems 和 reused。
reused() |
此信号在项目被重用后发出。此时,该项目已从池中取出并放置在内容视图中,并且已更新了模型属性,如索引、行和列。
当重用项目时,模型不提供的其他属性不会改变。您应该避免在委托内存储任何状态,但如果您确实存储了状态,请在接收到此信号时手动重置该状态。
此信号在重用项目时发出,而不仅仅是项目首次创建时。
只有当 reuseItems 属性设置为 true
时,才会发出此信号。
注意:相应的事件处理器是 onReused
。
另请参阅:重用项、reuseItems 和 pooled。
方法文档
|
返回表格中指定的 position 的单元格。 position 应相对于 内容项。如果没有已加载的单元格与 position 交集,则返回值将为 point(-1, -1)
。
如果将 includeSpacing 设置为 true
,则一个单元格的边界框将考虑包含相邻边的一半 rowSpacing 和 columnSpacing。默认值是 false
。
这是调用 cellAtPosition(Qt.point(x, y), includeSpacing)
的便捷方式。
clearColumnWidths() |
清除使用 setColumnWidth() 设置的所有列宽。
注意: 如果设置了 syncView,并且与 Qt.Horizontal syncDirection 一起,则同步视图将控制列宽。因此,在这种情况下,对该函数的任何调用将转发到同步视图。
另请参阅 setColumnWidth(),clearRowHeights(),以及 行高和列宽。
clearRowHeights() |
清除使用 setRowHeight() 设置的所有行高。
注意: 如果设置了 syncView,并且与 Qt.Vertical syncDirection 一起,则同步视图将控制行高。因此,在这种情况下,对该函数的任何调用将转发到同步视图。
另请参阅 setRowHeight(),clearColumnWidths(),以及 行高和列宽。
|
如果用户正在编辑单元格,调用此函数将停止编辑并销毁编辑代理实例。
此方法是在 Qt 6.5 中引入的。
另请参阅 edit(),TableView::editDelegate,以及 Editing cells。
|
返回指定 列 的宽度。如果该列未加载(因此不可见),则返回值将是 -1
。
此方法是在 Qt 6.2 中引入的。
另请参阅 setColumnWidth(),columnWidthProvider,implicitColumnWidth(),isColumnLoaded(),以及 行高和列宽。
|
此函数开始对表示 modelIndex 的单元格进行编辑会话。如果用户已在编辑另一个单元格,则该会话结束。
通常您可以通过使用 editTriggers 来指定启动编辑会话的不同方式。如果这还不充分,您可以使用此函数。为了完全控制单元格编辑并使 TableView 不干涉,请将 editTriggers 设置为 TableView.NoEditTriggers
。
注意:在 选择模型 中,将更改 selectionModel 的 current index 为 modelIndex。
此方法是在 Qt 6.5 中引入的。
另请参阅 closeEditor(),editTriggers,TableView::editDelegate,以及 编辑单元格。
qreal explicitColumnWidth(int column) |
返回使用 setColumnWidth 设置的 列 的宽度。这个宽度可能不同于列的实际宽度,如果使用了 columnWidthProvider。要获取列的实际宽度,请使用 columnWidth。
等于 0
的返回值表示该列被指明要隐藏。等于 -1
的返回值表示尚未为该列设置显式宽度。
注意: 如果设置了 syncView,并且与 Qt.Horizontal syncDirection 一起,则同步视图将控制列宽。因此,在这种情况下,对该函数的任何调用将转发到同步视图。
另请参阅 setColumnWidth,columnWidth,以及 行高和列宽。
qreal explicitRowHeight(int row) |
返回使用 setRowHeight 设置的 行 的高度。这个高度可能不同于列的实际高度,如果使用了 rowHeightProvider。要获取行的实际高度,请使用 rowHeight。
等于 0
的返回值表示该行被指明要隐藏。等于 -1
的返回值表示尚未为该行设置显式高度。
注意: 如果设置了 syncView,并且与 Qt.Vertical syncDirection 一起,则同步视图将控制行高。因此,在这种情况下,对该函数的任何调用将转发到同步视图。
另请参阅 setRowHeight,rowHeight,以及 行高和列宽。
forceLayout() |
模型变化的响应被分批处理,以确保每一帧只处理一次。这意味着在脚本执行期间,TableView 会延迟显示任何更改。更改属性时也是如此,例如 rowSpacing 或 leftMargin。
这种方法迫使 TableView 立即更新布局,以便任何最近的更改都能生效。
调用此函数会重新评估每行和每列的大小和位置。如果分配给 rowHeightProvider 或 columnWidthProvider 的函数返回的值与之前分配的值不同时,则需要此操作。
返回指定 列 的隐式宽度。如果该列未加载(因此不可见),则返回值将为 -1
。
列的隐式宽度是该列中当前加载的委托项中找到的最大 implicitWidth。不会考虑由 columnWidthProvider 返回的宽度。
此方法是在 Qt 6.2 中引入的。
另请参阅 columnWidthProvider、columnWidth()、isColumnLoaded() 以及 行高和列宽。
返回指定 行 的隐式高度。如果该行未加载(因此不可见),则返回值将为 -1
。
行的隐式高度是该行中当前加载的委托项中找到的最大 implicitHeight。不会考虑由 rowHeightProvider 返回的高度。
此方法是在 Qt 6.2 中引入的。
另请参阅 rowHeightProvider、rowHeight()、isRowLoaded() 以及 行高和列宽。
返回映射到视图中 行 和 列 的 QModelIndex。
行 和 列 应该是视图中的行和列(表格行和表格列),而不是模型中的行和列。对于普通的 TableView,这相当于调用 model.index(row, column).
但对于 TableView 的子类,如 TreeView,其中数据模型封装在内部代理模型中,该模型将树结构扁平化为表格,则需要使用此函数来解决模型索引。
此方法自 Qt 6.4.3 以来引入。
另请参阅 rowAtIndex() 和 columnAtIndex()。
如果指定的列已加载,则返回true
。
当TableView加载了显示该列所需的项目时,便认为该列已被加载。这也通常意味着该列对用户来说是可见的,但并非总是如此。
此函数可以在需要迭代列的项目时使用,例如从columnWidthProvider中,以确保项目可用于迭代。
此方法是在 Qt 6.2 中引入的。
如果指定的行已加载,则返回true
。
当TableView加载了显示该行所需的项目时,便认为该行已被加载。这也通常意味着该行对用户来说是可见的,但并非总是如此。
此函数可以在需要迭代行的项目时使用,例如从rowHeightProvider中,以确保项目可用于迭代。
此方法是在 Qt 6.2 中引入的。
如果已加载,则在cell处返回代理项目;否则返回null
。
注意:通常只加载视图中的项目。一旦一个单元格从视图中滑动出来,其中的项目不是卸载就是转移到回收池中。因此,不应存储返回值。
返回表示index的单元格的实例化代理项目。如果项目没有被加载,则值将是null
。
注意:通常只加载视图中的项目。一旦一个单元格从视图中滑动出来,其中的项目不是卸载就是转移到回收池中。因此,不应存储返回值。
注意:如果模型不是QAbstractItemModel,您也可以使用itemAtCell(Qt.point(column, row))。但请注意,point.x
映射到列,point.y
映射到行。
此方法是在 Qt 6.5 中引入的。
|
这是一个方便的函数,用于执行
modelIndex(cell.y, cell.x)
单元格只是一个将行和列合并为一个类型的点。
注意:point.x
将映射到列,point.y
将映射到行。
此方法是在 Qt 6.4 中引入的。
根据mode指定将contentX和contentY定位,以便cell处于mode指定的位置。 mode是可以是以下以下选项的或组合
常量 | 描述 |
---|---|
TableView.AlignLeft | 将单元格定位在视图的左侧。 |
TableView.AlignHCenter | 将单元格定位在视图的水平中心。 |
TableView.AlignRight | 将单元格定位在视图的右侧。 |
TableView.AlignTop | 将单元格定位在视图的顶部。 |
TableView.AlignVCenter | 将单元格放置在视图的垂直中心。 |
TableView.AlignBottom | 将单元格放置在视图的底部。 |
TableView.AlignCenter | 相当于 (TableView.AlignHCenter | TableView.AlignVCenter) |
TableView.Visible | 如果单元格的任何部分可见,则不采取任何操作。否则移动内容项,使整个单元格变得可见。 |
TableView.Contain | 如果整个单元格可见,则不采取任何操作。否则移动内容项,使整个单元格变得可见。如果单元格比视图大,则优先考虑单元格的左上部分。 |
如果没有指定垂直对齐方式,则忽略垂直定位。水平对齐也是如此。
可选地,您可以指定 offset 以在目标对齐的基础上移动 contentX 和 contentY 额外的像素数。例如,如果您想定位视图,使得单元格 [10, 10] 以 5 像素的边距位于左上角,您可以这样做
从 Qt 6.4 开始,您可以指定一个 subRect 以将位置定位在单元格内的一个矩形上,而不是整个单元格的边界矩形上。如果单元格,例如,比视图大,并且您想确保其中的特定部分可见,这将很有用。《子矩形需要是有效的,则应予以考虑。
注意:不建议使用 contentX 或 contentY 定位视图到特定的单元格。这是不可靠的,因为从表的开始删除项不会导致所有其他项重新定位。《TableView》有时也可以在近似位置上放置行和列,以优化速度。唯一的例外是如果单元格已经在视图中可见,这可以通过调用itemAtCell()在事先进行检查。
应在组件完成之后调用方法。为了在启动时定位视图,此方法应由 Component.onCompleted 调用。例如,要定位视图的末尾
Component.onCompleted: positionViewAtCell(Qt.point(columns - 1, rows - 1), TableView.AlignRight | TableView.AlignBottom)
注意:此函数的第二个参数以前是 Qt.Alignment。为了向后兼容,该枚举仍然可以使用。在 Qt 6.4 中使用 PositionMode 进行更改。
另请参阅:animate.
返回给定row的高度。如果行未加载(因此不可见),返回值将为-1
。
此方法是在 Qt 6.2 中引入的。
另请参阅setRowHeight()、rowHeightProvider、implicitRowHeight()、isRowLoaded()和行高和列宽。
将列column的显式宽度设置为size。
如果您想读取使用此函数设置的值,应使用explicitColumnWidth。 columnWidth()将返回列的实际大小,如果设置了columnWidthProvider,则可能不同。
当
columnWidthProvider: function(column) { let w = explicitColumnWidth(column) if (w >= 0) return Math.max(100, w); return implicitColumnWidth(column) }
如果size等于0
,则列将被隐藏。如果size等于-1
,则列将重置为使用implicitColumnWidth。
注意:如果您更改了model,您设置的尺寸不会清除。要清除尺寸,您需要显式调用clearColumnWidths。
注意: 如果设置了 syncView,并且与 Qt.Horizontal syncDirection 一起,则同步视图将控制列宽。因此,在这种情况下,对该函数的任何调用将转发到同步视图。
注意:对于具有许多列的模型,在启动时使用setColumnWidth()为所有列设置宽度可能不太理想。这将消耗启动时间和内存(用于保存所有宽度)。更可扩展的方法是使用columnWidthProvider,或者依赖代理的隐式宽度。一个columnWidthProvider
只在需要时调用,不会受到模型大小的约束。
另请参阅columnWidth()、explicitColumnWidth()、setRowHeight()、clearColumnWidths()和行高和列宽。
将行row的显式高度设置为size。
如果您想要读取使用此功能设置的值,应使用 explicitRowHeight 获取。 rowHeight 将返回行的实际高度,如果一个设置了 rowHeightProvider,则该值可能不同。
当 TableView 需要解析行的高度时,它将首先尝试调用 rowHeightProvider。只有在没有提供商设置的情况下,该函数设置的值才会被默认使用。但是,您可以从提供商内部调用 explicitRowHeight(),并在必要时对值进行调整,例如始终在某一定范围内。下面的片段展示了如何进行操作。
rowHeightProvider: function(row) { let h = explicitRowHeight(row) if (h >= 0) return Math.max(100, h); return implicitRowHeight(row) }
如果 size 等于 0
,则该行将被隐藏。如果 size 等于 -1
,则该行将重置为使用 implicitRowHeight。您可以指定超出模型大小的行的行大小。
注意:如果您更改了 model,设置的值不会被清除。为了清除大小,您需要显式地调用 clearRowHeights。
注意: 如果设置了 syncView,并且与 Qt.Vertical syncDirection 一起,则同步视图将控制行高。因此,在这种情况下,对该函数的任何调用将转发到同步视图。
注意:对于具有许多行的模型,在启动时使用 setRowHeight() 设置所有行的初始高度可能不是最优的。这将消耗启动时间和内存(用于存储所有高度)。一种更可缩放的方法是使用 rowHeightProvider,或者依赖于代理的隐式高度。只有在实际需要时才会调用 rowHeightProvider
,且不受模型大小的影响。
© 2024 Qt公司。此处包含的文档贡献版权属于其各自的所有者。此处提供的文档授权按自由软件基金会发布的 GNU自由文档许可证版本1.3 的条款使用。Qt及其相应标志是芬兰及全球其他国家的 Qt公司商标。所有其他商标均为其各自所有者的财产。