Qt QTreeView在添加到模型时不会更新

时间:2013-05-13 20:14:55

标签: c++ qt

我可以在public Git repository on BitBucket上找到与此问题相关的源代码。

我正在尝试使用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>());

所以我需要提出topLeft和bottomRight QModelIndex实例。如何从上面代码段中的 item1 构建/获取这些内容?

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

2 个答案:

答案 0 :(得分:3)

来自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 protected functionssignals

视图连接到这些信号,以了解模型数据何时更改并重新排列内部数据。这些函数在内部发出信号,以便您在视图发生时轻松发出警告。但信号只能由抽象类发出。

  

连接到此信号的组件使用它来适应变化   模型的尺寸。它只能由QAbstractItemModel发出   实现,并且不能在子类代码中显式发出。

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

编辑以回答您的评论:

确实,Items应该引用模型并告诉它有关更改,检查来自QStandardItem的这些行:

void QStandardItem::emitDataChanged()

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

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

也许您应该尝试使用QStandardItemQStandardItemModel。 直接或子类化。它会隐藏很多丑陋的东西。

答案 1 :(得分:0)

这也是一种不太恰当但更简单的方法 - emit layoutChanged()而不是dataChanged()。更多信息 - https://stackoverflow.com/a/41536459/635693