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

2022-01-19 00:00:00 qt qtquick2 qml c++ qtquickcontrols

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

I have a QML TreeView that gets data through a QStandardItemModel. When the application is running, I press a button which adds a new entry. I know the data is changing, but the QML TreeView is not updating. I've also tried beginResetModel() and endResetModel(). The data is correctly displayed in the TreeView upon loading the application, but the TreeView does not change when modifying the data in the model.

treeviewmodel.cpp

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

推荐答案

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

I hope this example helps. Unfortunately, I don't have your whole code to see where the problem is.

也许关键是 dataroleNames 方法.

Maybe the keys are the data and roleNames methods.

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

In this example, we also have a button called addButton to add new items.

ma??in.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;
}

相关文章