0

我需要创建一个 QML 应用程序,其中包含由 xml 文件定义的项目页面。xml 必须在 C++ 中解析。每个项目页面将是一个 StackView 页面,其中包含项目的 ListView。页面上的每个项目都有几个值定义文本、颜色、大小等。

首先,我的 DOM 模型创建基于 Qt Simple DOM Model Example。该模型使用 QAbstractItemModel 包装。我已经使用 rootContext->setContextProperty 将 C++ 模型暴露给 QML。我正在努力在 StackView 页面之间拆分数据。我假设我需要将分层模型的不同级别(页面父项和项子项)分配给不同的 UserRoles,以便将它们过滤到 QML 视图,但我正在努力寻找任何合适的示例来说明如何解决这个问题。

所以我的问题是:

您能否向我展示一个将 UserRoles 分配给 C++ DOM 模型的示例以及用于按 UserRole层次级别返回项目数据的关联数据方法?

或者

我是否走错了方向,有更好的方法来实现这一目标吗?

4

1 回答 1

0

OK, I've now got this going. After some more playing I decided to select the data by xml Node name - I used "Page" & "Item". If anyone else is looking at hierarchical models in C++ and views in QML the other key requirement I found to implementing a solution is the QML DelegateModel (formally VisualDataModel). Here are the snippets that directly answer the questions...

From DomModel.h

public:

    enum menuRoles
    {
        PageNumberRole = Qt::UserRole + 1,
        PageNameRole,
        ItemNumberRole,
        ItemNameRole
    };

...

QVariant data(const QModelIndex &index, int role) const;

...

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

From DomModel.cpp

QVariant DomModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();
    else
    {
        DomItem *item = static_cast<DomItem*>(index.internalPointer());
        QDomNode node = item->node();
        if(node.nodeName() == "Page")
        {
            switch (role)
            {
            case PageNumberRole:
                return node.attributes().namedItem("number").nodeValue();
                break;

            case PageNameRole:
                return node.attributes().namedItem("name").nodeValue();
                break;

            default:
                return QVariant();
                break;
            }
        }
        else if(node.nodeName() == "Item")
        {
            switch (role)
            {
            case ItemNumberRole:
                return node.attributes().namedItem("number").nodeValue();
                break;

            case ItemNameRole:
                return node.attributes().namedItem("name").nodeValue();
                break;

            default:
                return QVariant();
                break;
            }
        }
        else
            return QVariant();
    }
}

...

QHash<int, QByteArray> DomModel::roleNames() const
{
    // This tells the subscribing views what data roles are available
    // Any changes must be reflected in the DomModel::data function
    QHash<int, QByteArray> roles;
    roles[PageNumberRole] = "pageNumber";
    roles[PageNameRole] = "pageName";
    roles[ItemNumberRole] = "itemNumber";
    roles[ItemNameRole] = "itemName";
    return roles;
}
于 2013-10-04T18:55:48.493 回答