【问题标题】:Using custom QItemDelegate with a QSortFilterProxyModel将自定义 QItemDelegate 与 QSortFilterProxyModel 一起使用
【发布时间】:2017-07-04 19:00:24
【问题描述】:

我有一个自定义 QSortFilterProxyModel 只显示表中的某些行和列。我还有一个自定义 QItemDelegate 来控制如何绘制表格中的某些值。我只是将委托应用于需要它的列,问题似乎是当我让代理模型隐藏某些列时,它会弄乱委托。

例如,假设我有 A-G 列,我将自定义委托应用于 F 列。

A  B  C  D  E  F  G
-------------------
o  o  o  o  o  X  o
o  o  o  o  o  X  o
o  o  o  o  o  X  o

如果我的代理模型没有显示 B 列,我的委托最终会被应用到 G 列。

A  C  D  E  F  G
----------------
o  o  o  o  o  X
o  o  o  o  o  X
o  o  o  o  o  X

我已经能够通过调用隐藏视图上的列而不是代理模型中的列来解决该问题

table->setColumnHidden(B, true);

我认为这可行,但这是唯一的解决方案吗?委托和代理模型类不能更好地协同工作似乎是一个错误,就像您可以在同一模型上使用其中一个但不能同时使用一样。

【问题讨论】:

  • 据我所知,它按预期工作:项目委托应用于视图的列,这应该与模型无关。此外,您的模型代理模型,因此它被应用于正确的列。
  • 我想你是对的@cbuchart。我想这是有道理的,当我在视图上调用 setItemDelegateForColumn 时,它将是我指定的视图的列,而不是模型的列。如果您知道您使用的代理模型可能会更改列号,我认为您在下面提出的答案将是一个有效的解决方法。
  • 你可以做一个 qobject_cast 来检查模型是否是代理模型。

标签: c++ qt qabstractitemmodel qitemdelegate


【解决方案1】:

您可以尝试mapToSource 过滤索引(每列一个)并检查原始列并根据它设置相应的项目委托。

for (int i = 0; i < proxy->columnCount(); ++i) {
  if (proxy->mapToSource(proxy->index(0, i)).column() == 6) {
    table->setItemDelegateForColumn(i, yourDelegate);
  }
}

【讨论】:

  • 这似乎可行,但我不得不这样做似乎很奇怪。我希望视图或代理模型会自动执行此操作。我会试一试,如果它按预期工作,我会接受它作为答案。
  • 是的,遗憾的是它不会是自动的,或者至少模型可以像建议其他角色(如文本对齐)一样建议项目委托。
  • 对不起,我忘了这一切。我想我尝试了这种方法,但它也没有奏效。我最终只是在视图上调用了 setColumnVisible()。
【解决方案2】:

这是不在显示代理中使用列位置检测的众多充分理由之一。如果您让用户重新排列视图中的列,那也是一个问题。我不认为这是一个错误,但我过去曾希望有一种方法可以在项目模型级别分配默认委托。也许作为一个角色或其他东西。

无论如何,如果您可以控制数据,一个简单的解决方法是将列/字段 ID 直接存储在数据本身中,作为自定义数据角色,例如modelIndex.setData(FIELD_ONE, Qt::UserRole + 1)(例如,FIELD_ONE 是您的列的一些枚举)。然后代理可以检查该角色并知道该做什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-15
    • 2016-02-29
    • 2017-09-30
    • 2018-04-01
    相关资源
    最近更新 更多