#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.