【问题标题】:Using QAbstractItemModel to return QQuickPaintedItem for use in QML delegate使用 QAbstractItemModel 返回 QQuickPaintedItem 以在 QML 委托中使用
【发布时间】:2014-07-03 16:46:37
【问题描述】:

我实现了 QQuickPaintedItem 的一个子类以在 QML 中使用,它在通过注册时独立工作

qmlRegisterType<T>

此类的实例在应用程序启动时创建,并放入存储在 QAbstractItemModel 子类中的 QList 中。我认为我可以轻松地在模型的数据方法中返回每个对象,并将它们用作 QML ListViews 委托。 现在看起来像这样:

模型.cpp:

QVariant AbteilungsModel::data(const QModelIndex &index, int role) const
{
    if(index.isValid() && role == Qt::DisplayRole)
    {
        Abteilung* a = static_cast<Abteilung*>(index.internalPointer());
        return QVariant::fromValue(a);
    }
}

main.qml:

ListView {
    id: abteilungenListView
    anchors.fill: parent
    spacing: 5
    model: abteilungen
    delegate: modelData
}

当然,我通过以下方式在 QML 中提供了该模型

void QQmlContext::setContextProperty(const QString & name, QObject * value)

但我不知道如何正确声明 ListViews 委托,因为“modelData”不起作用。

有没有人知道这是否可能,或者你们有更好的解决方案吗? 任何帮助表示赞赏! :)

【问题讨论】:

    标签: qt qml qt-quick qabstractitemmodel


    【解决方案1】:

    这可能是可能的,但这与整个 MVC 理念背道而驰。你的模型不应该知道你的代表。举个简单的例子:

    main.cpp

    #include <QGuiApplication>
    #include <QtQml>
    #include <QtQuick>
    
    class Abteilung : public QQuickPaintedItem
    {
        Q_OBJECT
    public:
        Abteilung() {
        }
    
        void paint(QPainter *painter) {
            painter->setPen(Qt::red);
            painter->drawRect(boundingRect().adjusted(0, 0, -painter->pen().width(), -painter->pen().width()));
        }
    };
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        qmlRegisterType<Abteilung>("Test", 1, 0, "Abteilung");
    
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
    
        return app.exec();
    }
    
    #include "main.moc"
    

    main.qml

    import QtQuick 2.2
    import QtQuick.Controls 1.1
    import Test 1.0
    
    ApplicationWindow {
        visible: true
        width: 640
        height: 480
    
        ListView {
            id: abteilungenListView
            anchors.fill: parent
            spacing: 5
            model: ListModel {
                Component.onCompleted: {
                    for (var i = 0; i < 100; ++i) {
                        append({name: i});
                    }
                }
            }
    
            delegate: Abteilung {
                width: abteilungenListView.width
                height: 40
            }
        }
    }
    

    【讨论】:

    • 所以我必须根据模型返回的内容在 QML 中设置我的 QQuickPaintedItem 派生类的属性,我做对了吗?但它们已经在其他实例中设置,因为它们是在应用程序启动时从数据库中读取的。
    • 是的,您应该在 QML 中设置它们,其中每个委托都有模型中特定索引的相关数据。我不知道您所说的“但是它们已经在其他实例中设置,因为它们是在应用程序启动时从数据库中读取的。”。
    • 这样做意味着每个对象都有 2 个实例。一个在 C++ 端存储信息以向模型提供数据,另一个在 QML 端绘制项目,对吧?
    • 不看完整代码就很难说。据我从您的问题中了解到,该绘图是在 QQuickPaintedItem 子类中完成的。该子类应该定义一些可以从委托的 QML 实例中设置的属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-10
    • 2020-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多