简体   繁体   English

添加到模型时 Qt QTreeView 不更新

[英]Qt QTreeView not updating when adding to model

The source code relating to this question is available on my public Git repository on BitBucket .与此问题相关的源代码可在我在 BitBucket上的公共 Git 存储库中找到

I'm trying to dynamically add some items to a QTreeView model using the following code in mainwindow.cpp :我试图动态地添加一些资料转移到QTreeView使用下面的代码模型mainwindow.cpp

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);
}

This works when run from within my MainWindow constructor, just after ui->setupUi(this) , but I need this to run from within an event filter, but the same code doesn't get the QTreeView updating.这在我的MainWindow构造函数中运行时有效,就在ui->setupUi(this) ,但我需要它从事件过滤器中运行,但相同的代码不会更新QTreeView When I set a breakpoint at mainwindow.cpp:70 and step through the next few lines, I can see the data is being added to the Model, but I need the QTreeView to refresh.当我在mainwindow.cpp:70设置断点并逐步执行接下来的几mainwindow.cpp:70 ,我可以看到数据正在添加到模型中,但我需要刷新QTreeView

I understand this is done by emitting dataChanged() , but not really sure how to do this.我知道这是通过发出dataChanged()来完成的,但不确定如何做到这一点。 The signal signature for the dataChanged signal looks as follows: dataChanged信号的信号签名如下所示:

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

so I need to come up with topLeft and bottomRight QModelIndex instances.所以我需要提出topLeftbottomRight QModelIndex实例。 How do I build/obtain these from item1 in the above snippet?我如何从上面的代码片段中的item1构建/获取这些?

Also, where does beginInsertRows() and endInsertRows() come into view with this, should I be calling these functions?此外, beginInsertRows()endInsertRows()哪里出现,我应该调用这些函数吗?

From QAbstractItemModel documentation:来自 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.

The other protected functions say similar things.其他受保护的函数也有类似的说法。

And insertRows() says: insertRows() 说:

If you implement your own model, you can reimplement this function if you want to support insertions.如果你实现了自己的模型,如果你想支持插入,你可以重新实现这个函数。 Alternatively, you can provide your own API for altering the data.或者,您可以提供自己的 API 来更改数据。 In either case , you will need to call beginInsertRows() and endInsertRows() to notify other components that the model has changed.无论哪种情况,您都需要调用 beginInsertRows() 和 endInsertRows() 来通知其他组件模型已更改。

Take a look to QAbstractItemModel protected functions and signals查看 QAbstractItemModel 受保护的函数信号

Views connect to those signals to know when model data changes and rearrange data inside.视图连接到这些信号以了解模型数据何时更改并重新排列内部数据。 The functions emit the signals internally to make it easy for you to warn the view when it has happenned.这些函数在内部发出信号,以便您在视图发生时轻松发出警告。 But signals can only be emitted by abstract class.但是信号只能由抽象类发出。

Components connected to this signal use it to adapt to changes in the model's dimensions.连接到该信号的组件使用它来适应模型尺寸的变化。 It can only be emitted by the QAbstractItemModel implementation, and cannot be explicitly emitted in subclass code.它只能由 QAbstractItemModel 实现发出,不能在子类代码中显式发出。

So you will have to stick to the methods.所以你必须坚持方法。

Edit in answer to your comment:编辑以回答您的评论:

Indeed, Items should have a reference to model and tell it about changes, check theses lines from QStandardItem:实际上,Items 应该引用模型并告诉它有关更改的信息,请检查 QStandardItem 中的这些行:

void QStandardItem::emitDataChanged() void QStandardItem::emitDataChanged()

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

( Note, how, in second, it calls model's rowsAboutToBeRemoved() and rowsRemoved() ) (注意,其次,它如何调用模型的 rowsAboutToBeRemoved() 和 rowsRemoved() )

Maybe you should try to use QStandardItem and QStandardItemModel .也许您应该尝试使用QStandardItemQStandardItemModel Either direct or subclassing.直接或子类化。 It will hide a lot of ugly stuff.它会隐藏很多丑陋的东西。

There's also a less proper but much easier way to achieve this - emit layoutChanged() instead of dataChanged() .还有一种不太合适但更简单的方法来实现这一点 - emit layoutChanged()而不是dataChanged() More info - https://stackoverflow.com/a/41536459/635693更多信息 - https://stackoverflow.com/a/41536459/635693

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM