TableView 中不显示数据

Posted

技术标签:

【中文标题】TableView 中不显示数据【英文标题】:Data is not displayed in TableView 【发布时间】:2014-08-15 15:41:05 【问题描述】:

我尝试使用 C++ 模型构建简单的 TableView。我的表具有与返回 rowCount 和 columnCount 方法一样多的行和列。这意味着,模型与视图“连接”,但在每个单元格中不显示消息:“某些数据”

这是我的代码:

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

和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 

            

我哪里出错了?

【问题讨论】:

【参考方案1】:

简答

因为您的 QML 不要求 Qt::DisplayRole。将您的 TableVievColumn 更改为

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

QML 现在请求Qt::DisplayRole,并且“一些数据”显示在此列中。

长答案

QML 要求三个用户定义的角色:“id”、“name”和“duration”。但是,这三个角色不是内置角色。因此,您需要在模型类中实现这三个角色。

首先,您应该为模型提供一组角色。模型使用QAbstractItemModel::data 函数将数据返回给视图。 role的类型是int,我们可以在模型类中写一个枚举:

class PlaylistModel : public QAbstractTableModel

    Q_OBJECT
public:
    enum MyTableRoles 
    
        IdRole = Qt::UserRole + 1,
        NameRole,
        DurationRole
    
    //...
;

现在,在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();

接下来,为每个角色提供一个字符串到整数的映射。模型中的 role 是 int 类型,但在 QML 中 role 是字符串类型。 (请参阅TableViewColumn 中的角色属性。)因此,我们应该为每个角色提供字符串到整数的映射,以便 QML 可以正确地请求所需的数据。映射应在QAbstractItemModel::roleNames()中提供:

QHash<int, QByteArray> PlaylistModel::roleNames() const

    QHash<int, QByteArray> roleNameMap;
    roleNameMap[IdRole] = "id";
    roleNameMap[NameRole] = "name";
    roleNameMap[DurationRole] = "duration";

    return roleNameMap;

你的 QML 表格现在终于可以显示你想要的东西了。

一些参考资料

子类化QAbstractTableModel时,

您必须实现 rowCount()、columnCount() 和 data()。 index() 和 parent() 函数的默认实现由 QAbstractTableModel 提供。

使用C++ models in QML时,

可以通过重新实现 QAbstractItemModel::roleNames() 将 QAbstractItemModel 子类的角色暴露给 QML。

如果不重新实现roleNames 函数,则只能使用QAbstractItemModel::roleNames 中声明的默认角色。这就是简短答案有效的原因。

【讨论】:

使用QWidget也解决了问题:如果角色不是DisplayRole,数据函数需要返回无效的QVariant【参考方案2】:

你没有实现index方法。

根据文档,

当继承 QAbstractItemModel 时,至少你必须 实现index()、parent()、rowCount()、columnCount()和data()。 这些函数用于所有只读模型,并构成基础 可编辑模型。

换句话说,您必须实现自己的低级项目管理,AbstractItemModel 不会为您完成。您应该使用createIndex 创建索引并在必要时销毁它们等。

如果您不想玩这些游戏而只想实现自己的 quick&dirty 模型,请考虑继承 QStandardItemModel。

【讨论】:

我的代码在我使用 QTableView 小部件时有效,但在我使用 qml TableView 时无效。正如你所建议的,我添加了两种方法,但我仍然没有在每个单元格中收到“一些数据”消息。我编辑了我的代码。请检查此方法。 @iwaszek12 似乎一切正常。也许这是 QML 问题?也许有一些标志和角色问题?尝试:a)删除if (role == Qt::DisplayRole) 条件并为任何角色返回“一些数据”。 b) 将其更改为 if (role == Qt::DisplayRole || role == Qt::EditRole) 并在 else 中返回不是 QVariant(),而是 QAbstractItemModel::data(index, ...)。

以上是关于TableView 中不显示数据的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 在 iOS 7 中不根据其高度显示

标签在 iOS 6 中显示文本,但在 iOS 7 中不显示

在 iOS 9 中不鼓励在分离的视图控制器上显示视图控制器?

TableView 在 iOS 设备中不起作用

加或减按钮的值在swift中不更新。

标签栏在 iOS 中不可见