Qt QTreeView添加到模型时不更新

Qt QTreeView not updating when adding to model

本文关键字:更新 模型 QTreeView 添加 Qt      更新时间:2023-10-16

与这个问题相关的源代码可以在我在BitBucket上的公共Git存储库中获得。

我试图在mainwindow.cpp中使用以下代码动态添加一些项目到QTreeView模型:

if(dlg->exec() == QDialog::Accepted) {
    QList<QVariant> qList;
    qList << item.name << "1111 0000" << "0x00";
    HidDescriptorTreeItem *item1 = new HidDescriptorTreeItem(qList, hidDescriptorTreeModel->root());
    hidDescriptorTreeModel->root()->appendChild(item1);
}

当从我的MainWindow构造器内运行时,就在ui->setupUi(this)之后,但我需要从事件过滤器内运行,但相同的代码不会得到QTreeView更新。当我在mainwindow.cpp:70处设置一个断点并逐步执行接下来的几行时,我可以看到数据被添加到模型中,但我需要QTreeView来刷新。

我理解这是通过发射dataChanged()来完成的,但不确定如何做到这一点。dataChanged信号的信号签名如下:

void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>());

所以我需要拿出topLeftbottomRight QModelIndex实例。我如何在上面的代码片段中从item1构建/获取这些?

此外,beginInsertRows()endInsertRows()在哪里进入这个视图,我应该调用这些函数吗?

摘自QAbstractItemModel文档:

void QAbstractItemModel::beginInsertRows ( const QModelIndex & parent, int first, int last ) [protected]
Begins a row insertion operation.
When reimplementing insertRows() in a subclass, you must call this function before inserting data into the model's underlying data store.
The parent index corresponds to the parent into which the new rows are inserted; first and last are the row numbers that the new rows will have after they have been inserted.

其他受保护的函数也有类似的描述。

和insertRows()说:

如果你实现了你自己的模型,你可以在您需要支持插入。或者,您可以提供您的自己的API来修改数据。无论哪种情况,都需要调用beginInsertRows()和endInsertRows()来通知其他组件模型变了

看一下QAbstractItemModel受保护的函数和信号

视图连接到这些信号,以知道模型数据何时更改并重新排列内部数据。这些函数在内部发出信号,以便在发生这种情况时方便地警告视图。但是信号只能由抽象类发出。

连接到该信号的组件使用它来适应环境的变化模型的尺寸。它只能由QAbstractItemModel发出不能在子类代码中显式地发出。

所以你必须坚持使用方法。

编辑回复你的评论:

确实,Items应该有一个对模型的引用,并告诉它关于更改,检查QStandardItem中的这些行:

空白QStandardItem: emitDataChanged ()

void QStandardItem::removeRows(int row, int count)

(注意,它如何在第二步调用模型的rowsabouttoberremoved()和rowsRemoved())

也许你应该尝试使用QStandardItem和QStandardItemModel。直接或子类化。它会隐藏很多难看的东西

还有一种不太合适但更容易实现这一点的方法- emit layoutChanged()而不是dataChanged()。更多信息- https://stackoverflow.com/a/41536459/635693