QML TreeView 在向模型添加新数据后未在运行时更新

QML TreeView not updating at runtime after adding new data to the model

我有一个通过 QStandardItemModel 获取数据的 QML TreeView。当应用程序为 运行 时,我按下了一个添加新条目的按钮。我知道数据在变化,但 QML TreeView 没有更新。我也试过 beginResetModel()endResetModel()。加载应用程序时,数据在 TreeView 中正确显示,但在修改模型中的数据时,TreeView 不会更改。

treeviewmodel.cpp

#include <QDebug>
#include <QStandardItemModel>
#include "treeviewmodel.h"

TreeViewModel::TreeViewModel(QObject *parent) :
    QStandardItemModel(parent)
{
    m_roleNameMapping[TreeViewModel_Role_Name] = "name_role";

    QStandardItem* entry;
    entry = new QStandardItem(QString("my_entry"));
    entry->setData("abc", TreeViewModel_Role_Name);

    auto childEntry = new QStandardItem( "my_child_entry" );
    childEntry->setData( "def",TreeViewModel_Role_Name);
    entry->appendRow(childEntry);
    appendRow( entry );

}
TreeViewModel& TreeViewModel::Instance()
{
    static TreeViewModel instance; //Guaranteed to be destroyed
    return instance;
}
void TreeViewModel::addEntry()
{
    qDebug () << "Adding entry...";

    QStandardItem* entry;
    entry = new QStandardItem(QString("my_entry"));
    entry->setData("Second Entry", TreeViewModel_Role_Name);
    auto childEntry = new QStandardItem( "my_child_entry" );
    childEntry->setData( "Second Entry Child",TreeViewModel_Role_Name);
    entry->appendRow(childEntry);
    appendRow( entry );
    qDebug () << rowCount(); //Increases everytime I call the function
                             //Data is being added
}
QHash<int, QByteArray> TreeViewModel::roleNames() const
{
    return m_roleNameMapping;
}

main.qml

import treeModel 1.0
...
MyTreeModel {
    id: theModel
}

//Left Tree View
Rectangle {
    id: leftView
    Layout.minimumWidth: 50
    width: 200
    //Layout.fillWidth: true
    color: "white"
    TreeView {
        id: treeView
        anchors.fill: parent
        model: theModel
        TableViewColumn {
            role: "name_role"
            title: "Name"
        }
        TableViewColumn {
            role: "description_role"
            title: "Description"
        }
    }
}

ToolButton {
    iconSource: "lock.png"
    onClicked: {
    treeviewmodel.addEntry()
    }
}

main.cpp

QQmlContext* treeViewModelCtx = engine.rootContext();
treeViewModelCtx->setContextProperty("treeviewmodel", &TreeViewModel::Instance());

//Register types
qmlRegisterType<TreeViewModel>("treeModel", 1, 0, "MyTreeModel" );

希望这个例子对您有所帮助。不幸的是,我没有你的完整代码来查看问题出在哪里。

也许关键是 dataroleNames 方法。

在这个例子中,我们还有一个名为 addButton 的按钮来添加新项目。

main.cpp

#include "animalmodel.h"

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <qqmlcontext.h>
#include <qqml.h>

int main(int argc, char ** argv)
{
    QGuiApplication app(argc, argv);

    AnimalModel model;
    model.addAnimal("Wolf", "Medium");
    model.addAnimal("Polar bear", "Large");
    model.addAnimal("Quoll", "Small");

    QQmlApplicationEngine engine;

    QQmlContext *ctxt = engine.rootContext();
    ctxt->setContextProperty("myModel", &model);

    engine.load(QUrl(QStringLiteral("qrc:/view.qml")));

    return app.exec();
}

animalmodel.h

#ifndef ANIMALMODEL_H
#define ANIMALMODEL_H

#include <QStandardItemModel>

class AnimalModel : public QStandardItemModel
{
    Q_OBJECT
public:
    enum AnimalRoles {
        TypeRole = Qt::UserRole + 1,
        SizeRole
    };

    AnimalModel(QObject *parent = 0);

    Q_INVOKABLE void addAnimal(const QString &type, const QString &size);

    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;

protected:
    QHash<int, QByteArray> roleNames() const;
};

#endif // ANIMALMODEL_H

animalmodel.cpp

#include "animalmodel.h"

AnimalModel::AnimalModel(QObject *parent)
    : QStandardItemModel(parent)
{

}

void AnimalModel::addAnimal(const QString &type, const QString &size)
{
    QStandardItem* entry = new QStandardItem();
    entry->setData(type, TypeRole);

    auto childEntry = new QStandardItem();
    childEntry->setData(size, SizeRole);
    entry->appendRow(childEntry);

    appendRow( entry );
}

QVariant AnimalModel::data(const QModelIndex & index, int role) const {
    QStandardItem *myitem = itemFromIndex(index);

    if (role == TypeRole)
        return myitem->data(TypeRole);
    else if (role == SizeRole) {
        if (myitem->child(0) != 0)
        {
            return myitem->child(0)->data(SizeRole);
        }
    }

    return QVariant();
}

QHash<int, QByteArray> AnimalModel::roleNames() const {
    QHash<int, QByteArray> roles;
    roles[TypeRole] = "type";
    roles[SizeRole] = "size";
    return roles;
}