简体   繁体   English

数据未显示在TableView中

[英]Data is not displayed in TableView

I try to build simple TableView with model from C++. 我尝试使用C ++中的模型构建简单的TableView。 My table has as many rows and columns, as return rowCount and columnCount method. 我的表具有与返回rowCount和columnCount方法一样多的行和列。 This means, model is 'connected' with view, but in each cell does not display the message: 'Some data' 这意味着,模型已与视图“连接”,但在每个单元格中均不显示以下消息:“某些数据”

here is my code: 这是我的代码:

class PlaylistModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    PlaylistModel(QObject *parent=0): QAbstractTableModel(parent), rows(0){}

    int rowCount(const QModelIndex & /*parent*/) const
    {
        return 5;
    }
    int columnCount(const QModelIndex & /*parent*/) const
    {
        return 3;
    }
    QModelIndex index(int row, int column, const QModelIndex &parent) const {
         return createIndex(row, column);
    }
    QModelIndex parent(const QModelIndex &child) const {
         return child.parent();
    }
    QVariant data(const QModelIndex &index, int role) const{
        if (role == Qt::DisplayRole)
             {
               return QString("Some data");
             }
        return QVariant();
    }
(...)
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
PlaylistModel plModel(0);
engine.rootContext()->setContextProperty("myModel", &plModel);
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

and qml 和qml

TableView {
                id: trackList
                width: 100; height: 100
                model: myModel
                TableViewColumn { role: "id"; title: "Id"; width: 30 }
                TableViewColumn { role: "name"; title: "Name"; width: 100}
                TableViewColumn { role: "duration"; title: "Duration"; width: 20 }

            }

Where I make a mistake? 我在哪里弄错了?

Short answer 简短答案

Because your QML is not asking for Qt::DisplayRole . 因为您的QML不需要Qt::DisplayRole Change your TableVievColumn to 将您的TableVievColumn更改为

TableViewColumn { role: "display"; title: "xxx"; width: 20 }

The QML is now asking for Qt::DisplayRole , and "Some data" is shown in this column. QML现在要求Qt::DisplayRole ,并且在此列中显示“某些数据”。

Long answer 长答案

QML is asking for three user-defined roles: "id", "name", and "duration". QML要求三个用户定义的角色:“ id”,“ name”和“ duration”。 However, the three roles are not bulit-in roles. 但是,这三个角色不是临时角色。 Therefore you need to implement the three roles in your model class. 因此,您需要在模型类中实现这三个角色。

First, you should provide a set of roles to the model. 首先,您应该为模型提供一组角色。 The model returns data to views using QAbstractItemModel::data function. 该模型使用QAbstractItemModel::data函数将数据返回到视图。 The type of role is int, we can write an enum in the model class: role的类型是int,我们可以在模型类中编写一个枚举:

class PlaylistModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    enum MyTableRoles 
    {
        IdRole = Qt::UserRole + 1,
        NameRole,
        DurationRole
    }
    //...
};

Now, in the data function, returns the corresponding value any time the view is asking: 现在,在data函数中,无论何时视图问,都将返回相应的值:

QVariant PlaylistModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid()){return QVariant();}

    switch(role)
    {
    case IdRole:
        return GetIdFromMyTable(index);
    case NameRole:
        return GetNameFromMyTable(index);
    case DurationRole:
        return GetDurationFromMyTable(index);
    }
    //...
    return QVariant();
}

Next, provide a string-to-int mapping for each role. 接下来,为每个角色提供一个字符串到整数的映射。 The role in the model is in type of int, however in the QML the role is type of string. role的模型是int类型,但是在QML的role是字符串类型。 (see the role property in TableViewColumn .) Therefore we should provide a string-to-int mapping for each role so the QML can correctly asking for the required data. (请参见TableViewColumn的role属性。)因此,我们应该为每个角色提供一个字符串到int的映射,以便QML可以正确地请求所需的数据。 The mapping should be provided in QAbstractItemModel::roleNames() : 映射应在QAbstractItemModel::roleNames()

QHash<int, QByteArray> PlaylistModel::roleNames() const
{
    QHash<int, QByteArray> roleNameMap;
    roleNameMap[IdRole] = "id";
    roleNameMap[NameRole] = "name";
    roleNameMap[DurationRole] = "duration";

    return roleNameMap;
}

Finally your table in QML now can display the things you want. 最终,您现在在QML中的表可以显示所需的内容。

Some references 一些参考

When subclassing QAbstractTableModel , 子类化QAbstractTableModel时

you must implement rowCount(), columnCount(), and data(). 您必须实现rowCount(),columnCount()和data()。 Default implementations of the index() and parent() functions are provided by QAbstractTableModel. QAbstractTableModel提供了index()和parent()函数的默认实现。

When using C++ models in QML , 在QML中使用C ++模型时

The roles of a QAbstractItemModel subclass can be exposed to QML by reimplementing QAbstractItemModel::roleNames(). 通过重新实现QAbstractItemModel :: roleNames(),可以将QAbstractItemModel子类的角色暴露给QML。

And if you do not reimplement the roleNames function, you can use only the default roles declared in QAbstractItemModel::roleNames . 而且,如果不重新实现roleNames函数,则只能使用QAbstractItemModel :: roleNames中声明的默认角色。 And this is the reason why the short answer works. 这就是简短答案有效的原因。

You did not implemented index method. 您尚未实现index方法。

According to documentation, 根据文档,

When subclassing QAbstractItemModel, at the very least you must implement index() , parent(), rowCount(), columnCount(), and data(). 子类化QAbstractItemModel时,至少必须实现index() ,parent(),rowCount(),columnCount()和data()。 These functions are used in all read-only models, and form the basis of editable models. 这些功能在所有只读模型中使用,并构成可编辑模型的基础。

in other words, You have to implement your own low-level item management, AbstractItemModel will not do it for you. 换句话说,您必须实现自己的低级项目管理,AbstractItemModel不会为您执行此操作。 You should create indexes with createIndex and destroy them when nesessary etc. 您应该使用createIndex创建索引,并在必要时销毁它们。

If you don't want to play these games and just want to implement your own quick&dirty model, consider subclassing QStandardItemModel. 如果您不想玩这些游戏,而只想实现自己的快速脏模型,请考虑将QStandardItemModel子类化。

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

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