首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将QAbstractItemModel移植到QtQuick (不定义ItemDelegate)

如何将QAbstractItemModel移植到QtQuick (不定义ItemDelegate)
EN

Stack Overflow用户
提问于 2020-02-25 00:40:42
回答 1查看 37关注 0票数 0

我有一个Qt3D实体树的QAbstractItemModel树模型:

Qt3牙类型treemodel.h:

代码语言:javascript
复制
#define QT3DENTITYTREEMODEL_H

#include <QAbstractItemModel>
#include <Qt3DCore/QEntity>

class Qt3DEntityTreeModel : public QAbstractItemModel
{
    Q_OBJECT
public:
    Q_PROPERTY(Qt3DCore::QEntity * rootEntity READ rootEntity WRITE setRootEntity NOTIFY rootEntityChanged)

    explicit Qt3DEntityTreeModel(QObject *parent = nullptr);

    void setRootEntity(Qt3DCore::QEntity *rootEntity);
    Qt3DCore::QEntity * rootEntity() const;

    QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
    QModelIndex parent(const QModelIndex &child) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    Qt::ItemFlags flags(const QModelIndex &index) const override;

signals:
    void rootEntityChanged(Qt3DCore::QEntity *rootEntity);

private:
    Qt3DCore::QEntity *rootEntity_;
};

#endif // QT3DENTITYTREEMODEL_H

qt3dentitytreemodel.cpp:

代码语言:javascript
复制
#include "qt3dentitytreemodel.h"

Qt3DEntityTreeModel::Qt3DEntityTreeModel(QObject *parent)
    : QAbstractItemModel(parent)
{
}

void Qt3DEntityTreeModel::setRootEntity(Qt3DCore::QEntity *rootEntity)
{
    qDebug() << "Qt3DEntityTreeModel::setRootEntity" << rootEntity;

    auto old = rootEntity_;

    rootEntity_ = rootEntity;

    if(rootEntity_ != old)
        emit rootEntityChanged(rootEntity);
}

Qt3DCore::QEntity * Qt3DEntityTreeModel::rootEntity() const
{
    return rootEntity_;
}

QModelIndex Qt3DEntityTreeModel::index(int row, int column, const QModelIndex &parent) const
{
    if(!rootEntity_) return {};
    if(column != 0) return {};
    if(!parent.isValid())
    {
        if(row == 0) return createIndex(0, 0, rootEntity_);
    }
    else
    {
        auto entity = reinterpret_cast<Qt3DCore::QEntity*>(parent.internalPointer());
        if(!entity) return {};

        return createIndex(row, column, entity->childNodes().at(row));
    }
    return {};
}

QModelIndex Qt3DEntityTreeModel::parent(const QModelIndex &child) const
{
    if(!rootEntity_) return {};
    if(!child.isValid()) return {};

    auto entity = reinterpret_cast<Qt3DCore::QEntity*>(child.internalPointer());
    if(!entity) return {};

    auto parent = entity->parentNode();
    if(!parent) return {};

    auto grandParent = parent->parentNode();
    if(!grandParent) return createIndex(0, 0, parent);

    return createIndex(grandParent->childNodes().indexOf(parent), 0, parent);
}

QVariant Qt3DEntityTreeModel::data(const QModelIndex &index, int role) const
{    
    if(!rootEntity_) return {};
    if(!index.isValid()) return {};
    if(role != Qt::DisplayRole && role != DisplayRole) return {};

    auto entity = reinterpret_cast<Qt3DCore::QEntity*>(index.internalPointer());
    if(!entity) return {};

    QString data = entity->metaObject()->className();
    if(!entity->objectName().isEmpty())
            data += QString(" \"%1\"").arg(entity->objectName());
    return data;
}

QVariant Qt3DEntityTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    return {};
}

int Qt3DEntityTreeModel::rowCount(const QModelIndex &parent) const
{
    if(!parent.isValid()) return 1;

    auto entity = reinterpret_cast<Qt3DCore::QEntity*>(parent.internalPointer());
    if(!entity) return 0;
    return entity->childNodes().count();
}

int Qt3DEntityTreeModel::columnCount(const QModelIndex &parent) const
{
    return 1;
}

Qt::ItemFlags Qt3DEntityTreeModel::flags(const QModelIndex &index) const
{
    return {};
}

在QTreeView (QtWidgets)中显示时效果很好:

代码语言:javascript
复制
auto treeView = new QTreeView();
auto treeModel = new Qt3DEntityTreeModel(treeView);
treeModel->setRootEntity(rootEntity);
treeView->setModel(treeModel);
treeView->resize(640, 480);
treeView->show();

但是,当在QtQuick控件TreeView中使用时,我看不到项目文本,甚至无法展开根树项目:

代码语言:javascript
复制
Item {
    ...

    Qt3DEntityTreeModel {
        id: entityTreeModel
        rootEntity: root
    }

    TreeView {
        model: entityTreeModel
        TableViewColumn {
            title: "Name"
            width: 200
        }
    }

    Scene3D {
        id: scene3d

        Entity {
            id: root
            ...
        }
    }
}

我还尝试在Qt3DEntityTreeModel中显式定义一个角色

Qt3牙类型treemodel.h:

代码语言:javascript
复制
enum Roles {
    DisplayRole = Qt::UserRole + 1
};
QHash<int, QByteArray> roleNames() const override;

qt3dentitytreemodel.cpp:

代码语言:javascript
复制
QVariant Qt3DEntityTreeModel::data(const QModelIndex &index, int role) const
{    
    if(!rootEntity_) return {};
    if(!index.isValid()) return {};
    if(role != Qt::DisplayRole && role != DisplayRole) return {};
    ...
}

QHash<int, QByteArray> Qt3DEntityTreeModel::roleNames() const
{
    QHash<int, QByteArray> result;
    result.insert(DisplayRole, QByteArrayLiteral("display"));
    return result;
}

并在QtQuick TreeView的列中定义相应的角色属性:

代码语言:javascript
复制
TreeView {
    model: entityTreeModel
    TableViewColumn {
        title: "Name"
        role: "display"
        width: 200
    }
}

但还是什么都没显示。

要想在QtQuick的TreeView中使用自定义抽象项目模型,还需要做些什么吗?

EN

回答 1

Stack Overflow用户

发布于 2020-02-25 05:25:17

我想我找到了解释:模型是在Qt3D实体树“就绪”之前创建的。

如果我在视图加载后在C++中创建模型,然后将模型设置为上下文属性,它将在QML的TreeView中正确显示:

代码语言:javascript
复制
QQuickView view;
view.resize(500, 500);
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.setSource(QUrl("qrc:/main.qml"));

auto rootObject = view.rootObject();
auto rootEntity = rootObject->findChild<Qt3DCore::QEntity*>("theRootEntity");
qDebug() << "rootEntity:" << rootEntity;

auto treeModel = new Qt3DEntityTreeModel(&app);
treeModel->setRootEntity(rootEntity);

view.rootContext()->setContextProperty("theModel", treeModel);

view.show();

最根本的问题是我的模型没有监控对Qt3D实体树的更新,它也没有反映这样的更新。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60380349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档