Qt appendRow后带有QStandardItemModel的QSortFilterProxy模型不工作

Qt appendRow后带有QStandardItemModel的QSortFilterProxy模型不工作,qt,qt4,qstandarditemmodel,qsortfilterproxymodel,Qt,Qt4,Qstandarditemmodel,Qsortfilterproxymodel,这是我得到的: 一个QTreeViewwidget(*) 源模型MainModel继承自QStandardItemModel。没有重新实现虚拟data()const方法 代理MainFilterProxyModel继承自QSortFilterProxyModel 树: [PERIOD 1] [CHILD 1] [CHILD 2] [SUBCHILD 2.1] ... [CHILD N] [PERIOD 2] ... [PERIOD N] 因此,当我

这是我得到的:

  • 一个
    QTreeView
    widget(*)
  • 源模型
    MainModel
    继承自
    QStandardItemModel
    。没有重新实现虚拟
    data()const
    方法
  • 代理
    MainFilterProxyModel
    继承自
    QSortFilterProxyModel
树:

[PERIOD 1]
   [CHILD 1]
   [CHILD 2]
      [SUBCHILD 2.1]
      ...
   [CHILD N]
[PERIOD 2]
...
[PERIOD N]
因此,当我试图添加一个子行时,主要的问题就出现了,就像(**)代码一样。将文档添加到源模型后,筛选器代理模型不知道新行的情况,并且未在树上显示它

我确信当
appendRow
方法执行其工作时,代理没有从
QStandardItemModel
获取信号,因此代理无法筛选新行,也无法使其可见

有什么帮助吗

谢谢

PS:如果我关闭代理,一切都很好。但问题不在于代理。代理只是没有得到有关附加到主源模型的新行的信号


(*)这里是
QTreeView


(**)以下是我的附加函数:

void main model::addRow(const DocumentPtr&document,QStandardItem*parentItem)
{
断言(文件);
QList项目;

items建模的基类是
qastraditemmodel
。最好使用抽象类的方法来做你想做的事情。
QStandardItemModel
qastraditemmodel
的抽象方法的简单实现,大部分的
QStandardItemModel
新方法都被reimple使用mented抽象函数。下面是使用抽象类方法添加项和子项的代码:

QAbstractItemModel * pModel = new QStandardItemModel(parent);

int nRows = pModel->rowCount();
pModel->insertRow(nRows); // this will emit rowsAboutToBeInserted() and rowsInserted() signals
pModel->insertColumn(0); // this will emit columnsAboutToBeInserted() and columnsInserted() signals
const QModelIndex indexFirstItem = pModel->index(nRows, 0);
pModel->setData(indexFirstItem, "Item text"); // this will emit dataChanged() signal
int nChildRows = pModel->rowCount(indexFirstItem);
pModel->insertRow(nChildRows, indexFirstItem); // this will emit rowsInserted()
pModel->insertColumn(0, indexFirstItem); // we also need to do this for the item's children
const QModelIndex indexChild = pModel->index(nChildRows, 0, indexFirstItem);
pModel->setData(indexChild, "Child item text");
如果我们尝试使用QStandardItemModel方法进行同样的操作,它将如下所示:

QStandardItemModel *pModel = new QStandardItemModel(parent);
QStandardItem *pItem = new QStandardItem("Item text");
pItem->appendRow(new QStandardItem); // pItem is not yet added to pModel and rowsInserted won't be emitted
pModel->appendRow(pItem); // this will probably emit rowsInserted() signal but since we set tha text of the item when creating the pItem the dataChanged() signal won't be emitted.

因此,如果您使用
pItem->appendRow()
添加子项,并且如果pItem尚未添加到模型中,则可能无法获得
rowsinerted()
signal,因此代理模型不会被通知。根据我的经验,第一种方法工作得更好,而且更健壮,尽管你需要多写几行。直接使用
QStandardItemModel
方法通常会以缺少信号或其他令人头痛的问题结束。你只需要看看
QAbstractItemModel
QModelIndex
文档。

在所示示例中,您不是在模型中添加项目,而是在以示例中不可见的方式获取的QStandarditem中添加项目。您能否简化您的代码,使其完全可见并且仍然可以再现故障?@vtmarvin我真的不明白我有什么要这样做,但我把源文件放在这里:希望有帮助!好吧,如果你甚至没有显示MainFilterProxyModel的代码,我们怎么知道它为什么没有得到信号?@nus你是对的。这是代理头()和源()文件…@mosg我仍然无法跟踪您的程序流程,因为缺少main model.h。model_uu和proxy_uu是什么?它们是数据成员吗?您是否尝试将自定义代理替换为标准代理,只是为了查看错误是在代理中还是在主模型中?
QAbstractItemModel * pModel = new QStandardItemModel(parent);

int nRows = pModel->rowCount();
pModel->insertRow(nRows); // this will emit rowsAboutToBeInserted() and rowsInserted() signals
pModel->insertColumn(0); // this will emit columnsAboutToBeInserted() and columnsInserted() signals
const QModelIndex indexFirstItem = pModel->index(nRows, 0);
pModel->setData(indexFirstItem, "Item text"); // this will emit dataChanged() signal
int nChildRows = pModel->rowCount(indexFirstItem);
pModel->insertRow(nChildRows, indexFirstItem); // this will emit rowsInserted()
pModel->insertColumn(0, indexFirstItem); // we also need to do this for the item's children
const QModelIndex indexChild = pModel->index(nChildRows, 0, indexFirstItem);
pModel->setData(indexChild, "Child item text");
QStandardItemModel *pModel = new QStandardItemModel(parent);
QStandardItem *pItem = new QStandardItem("Item text");
pItem->appendRow(new QStandardItem); // pItem is not yet added to pModel and rowsInserted won't be emitted
pModel->appendRow(pItem); // this will probably emit rowsInserted() signal but since we set tha text of the item when creating the pItem the dataChanged() signal won't be emitted.