使用新数据更新QTreeView不正确

时间:2017-09-26 14:18:04

标签: c++ qt treeview qtreeview

从流行的Qt SimpleTreeModel开始,我希望能够使用新数据更新整个树视图。该示例仅在启动时填充树视图,之后不会更新树视图。

我对该示例进行了一些编辑(treeview现在在对话框中,因此我可以按" PushButton"更新树视图),当我更新树视图时,最顶层的TreeItems成为子TreeItems对于每个最顶层的TreeItem。当我在这种情况下更新树视图时,之前和之后应该是相同的数据相同,我不明白为什么之前和之后会有所不同。下面的屏幕截图更好地说明了问题:

更新前

enter image description here

更新后,您可以看到如果我点击多次使用的项目,它们都会突出显示,这是有道理的,因为它们都(可能)指向同一个项目(我不确定如何)。

enter image description here

我对SimpleTreeModel的编辑如下:

的main.cpp

#include "dialog.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    Q_INIT_RESOURCE(simpletreemodel);

    QApplication app(argc, argv);

    Dialog dialog;
    dialog.show();

    return app.exec();
}

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

#include <QFile>

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);

    QFile file(":/default.txt");
    file.open(QIODevice::ReadOnly);
    model = new TreeModel(file.readAll());
    file.close();

    ui->treeView->setModel(model);
}

Dialog::~Dialog()
{
    delete ui;
}

void Dialog::on_pushButton_clicked()
{
    model->redrawAll();
}

treeitem.cpp(与example完全相同,除了下面的新功能)

void TreeItem::removeChildren() {
    m_childItems.clear();
}

treemodel.cpp(与example完全相同,除了下面的新功能)。我将从rootItem中删除所有子项,以便我可以在每次更新时放入全新的数据。

TreeModel::TreeModel(const QString &data, QObject *parent)
    : QAbstractItemModel(parent)
{
    QList<QVariant> rootData;
    this->data1 = data;
    rootData << "Title" << "Summary";
    rootItem = new TreeItem(rootData);
    setupModelData(data.split(QString("\n")), rootItem);
}

void TreeModel::redrawAll() {
    rootItem->removeChildren();

    setupModelData(data1.split(QString("\n")), rootItem);

    emit dataChanged(QModelIndex(), QModelIndex());

}

编辑:我已将redrawAll函数修改为以下。结果与使用TreeModel::redrawAll()的上一个emit dataChanged(QModelIndex(), QModelIndex())函数更新后的屏幕截图相同。

void TreeModel::redrawAll() {
//    beginResetModel();
    rootItem->removeChildren();

    QFile file(":/default.txt");
    file.open(QIODevice::ReadOnly);
    QString data = file.readAll();
    setupModelData(data.split(QString("\n")), rootItem);
    file.close();

//    endResetModel();

//    emit dataChanged(QModelIndex(), QModelIndex());

    qDebug() << "TreeModel::redrawAll() " << rowCount() << columnCount();
// the output is TreeModel::redrawAll()  6 2
    QModelIndex topLeft = this->index(0, 0);
    QModelIndex bottomRight   = this->index(rowCount(), columnCount());
    emit dataChanged(topLeft, bottomRight);

}

1 个答案:

答案 0 :(得分:0)

您发出的dataChanged()信号是无稽之谈。不仅无效索引范围不允许,但dataChanged()仅表示数据项的内容更改,而不是树的结构。你似乎也在改变结构。

由于您似乎正在更改整个模型的内容,您应该表明您已重置模型:

void TreeModel::redrawAll() {
  beginResetModel();
  ...
  endResetModel();
}