QTreeView:multi-level 列的层次上下文
QTreeView: hierarchical context for multi-level columns
我正在寻找一种更好的方法来在树中显示 multi-level 分层数据,其中 每列的含义根据树中的级别而变化 。
我正在使用 QTreeView
和 QAbstractItemModel
来显示我的模型数据。
每个模型行都有不同数量的列和不同的列名称,具体取决于它在层次结构中的级别。
为了为树中显示的数据提供上下文,我需要为层次结构中的每个级别设置 header 列。
问题是 QTreeView
只有一组列 headers。
当前方法
目前,每次选定的行发生变化时,我都会更改 header。
我通过连接到树视图的 selectionModel
并在每次选择更改时用新的 QModelIndex
发出信号来做到这一点
void Window::slotOnSelectionChanged(const QItemSelection& new_selection, const QItemSelection& old_selection)
{
QItemSelectionModel* selection_model = _view->selectionModel();
QModelIndex index = selection_model->currentIndex();
if (index.isValid())
emit selectedIndexChanged(index);
}
在我的模型中,我连接到这个信号,当它触发时,存储选定的行,并强制列 header 更新
void Model::slotOnSelectedIndexChanged(QModelIndex index)
{
assert(index.isValid());
_selected_row = modelRow(index);
emit headerDataChanged(Qt::Horizontal, 0, _root->numColumns());
}
在 QAbstrateItemModel::headerData
回调中,我然后使用 selected_row
获取当前选定行的 header
QVariant Model::headerData(int i, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole)
{
switch (orientation)
{
case Qt::Horizontal:
return QVariant(_selected_row->header(i));
...
结果
结果如下所示 - 请注意 header 列如何随着所选行的变化而变化。
问题
仅查看视图并不能立即看出每个数据是什么,因此用户需要更改行才能查看每列的实际含义。
我想要某种嵌入式列 header 行,层次结构中每个级别 1 个。
像这样:
问题
- 这可能吗?
- 如果有更好的方法为树中的数据提供上下文,请提供建议。
根据 @Kuba Ober 的建议,我在树的每个层次结构中的位置 0 处添加了一个额外的行。它没有 children.
然后将模型配置为 index.row() == 0
的特殊情况,知道该行是 header 行而不是数据行。
例如:在 Model::flags
中,header 行不可编辑
Qt::ItemFlags Model::flags(const QModelIndex& index) const
{
Qt::ItemFlags item_flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
// header row is not editable
if (index.row() != 0)
item_flags |= Qt::ItemIsEditable;
return item_flags;
}
我现在 return headerData
的空字符串,因为 header 在树本身中
QVariant Model::headerData(int i, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole)
{
switch (orientation)
{
case Qt::Horizontal:
return QVariant(); // no column header, it's already in the tree
...
我还更改了 header 的背景颜色,使其突出显示
QVariant Model::data(const QModelIndex& index, int role) const
{
switch (role)
{
case Qt::BackgroundColorRole:
if (index.row() == 0) // header row
return QColor(Qt::darkGray);
break;
...
结果几乎就是我想要的
我正在寻找一种更好的方法来在树中显示 multi-level 分层数据,其中 每列的含义根据树中的级别而变化 。
我正在使用 QTreeView
和 QAbstractItemModel
来显示我的模型数据。
每个模型行都有不同数量的列和不同的列名称,具体取决于它在层次结构中的级别。
为了为树中显示的数据提供上下文,我需要为层次结构中的每个级别设置 header 列。
问题是 QTreeView
只有一组列 headers。
当前方法
目前,每次选定的行发生变化时,我都会更改 header。
我通过连接到树视图的 selectionModel
并在每次选择更改时用新的 QModelIndex
发出信号来做到这一点
void Window::slotOnSelectionChanged(const QItemSelection& new_selection, const QItemSelection& old_selection)
{
QItemSelectionModel* selection_model = _view->selectionModel();
QModelIndex index = selection_model->currentIndex();
if (index.isValid())
emit selectedIndexChanged(index);
}
在我的模型中,我连接到这个信号,当它触发时,存储选定的行,并强制列 header 更新
void Model::slotOnSelectedIndexChanged(QModelIndex index)
{
assert(index.isValid());
_selected_row = modelRow(index);
emit headerDataChanged(Qt::Horizontal, 0, _root->numColumns());
}
在 QAbstrateItemModel::headerData
回调中,我然后使用 selected_row
获取当前选定行的 header
QVariant Model::headerData(int i, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole)
{
switch (orientation)
{
case Qt::Horizontal:
return QVariant(_selected_row->header(i));
...
结果
结果如下所示 - 请注意 header 列如何随着所选行的变化而变化。
问题
仅查看视图并不能立即看出每个数据是什么,因此用户需要更改行才能查看每列的实际含义。
我想要某种嵌入式列 header 行,层次结构中每个级别 1 个。
像这样:
问题
- 这可能吗?
- 如果有更好的方法为树中的数据提供上下文,请提供建议。
根据 @Kuba Ober 的建议,我在树的每个层次结构中的位置 0 处添加了一个额外的行。它没有 children.
然后将模型配置为 index.row() == 0
的特殊情况,知道该行是 header 行而不是数据行。
例如:在 Model::flags
中,header 行不可编辑
Qt::ItemFlags Model::flags(const QModelIndex& index) const
{
Qt::ItemFlags item_flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
// header row is not editable
if (index.row() != 0)
item_flags |= Qt::ItemIsEditable;
return item_flags;
}
我现在 return headerData
的空字符串,因为 header 在树本身中
QVariant Model::headerData(int i, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole)
{
switch (orientation)
{
case Qt::Horizontal:
return QVariant(); // no column header, it's already in the tree
...
我还更改了 header 的背景颜色,使其突出显示
QVariant Model::data(const QModelIndex& index, int role) const
{
switch (role)
{
case Qt::BackgroundColorRole:
if (index.row() == 0) // header row
return QColor(Qt::darkGray);
break;
...
结果几乎就是我想要的