Использование QAbstractItemModel для возврата QQuickPaintedItem для использования в делегате QML

#qt #qml #qt-quick #qabstractitemmodel

#qt #qml #qt-быстрый #qabstractitemmodel

Вопрос:

Я реализовал подкласс QQuickPaintedItem для использования в QML, который работает сам по себе при регистрации через

 qmlRegisterType<T>
  

Экземпляры этого класса создаются при запуске приложения и помещаются в QList, который хранится внутри подкласса QAbstractItemModel. Я думал, что мог бы легко вернуть каждый из этих объектов в методе данных модели и использовать их в качестве делегата QML ListViews.
Теперь это выглядит так:

Model.cpp:

 QVariant AbteilungsModel::data(const QModelIndex amp;index, int role) const
{
    if(index.isValid() amp;amp; 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 amp; name, QObject * value)
  

но я не знаю, как правильно объявить делегат ListViews, поскольку «modelData» не работает.

У кого-нибудь есть идея, возможно ли это вообще, или у вас, ребята, есть решение получше? Любая помощь приветствуется! 🙂

Ответ №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
        }
    }
}
  

Комментарии:

1. Итак, я должен установить свойства моего производного класса QQuickPaintedItem в QML в соответствии с тем, что возвращает модель, я правильно понимаю? Но они уже установлены в других экземплярах, поскольку они считываются из базы данных при запуске приложения.

2. Да, вы должны установить их в QML, где у каждого делегата есть соответствующие данные для определенного индекса в модели. Я не знаю, что вы имеете в виду под «Но они уже установлены в других экземплярах, поскольку они считываются из базы данных при запуске приложения»..

3. Выполнение этого способа означает, что будет по 2 экземпляра каждого объекта. Тот, который хранит информацию для обеспечения модели данными на стороне C , и тот, который рисует элемент на стороне QML, верно?

4. Трудно сказать, не видя вашего полного кода. Рисование, насколько я понимаю из вашего вопроса, выполняется в QQuickPaintedItem подклассе. У этого подкласса должны быть определены некоторые свойства, которые могут быть установлены из экземпляров делегатов QML.