У меня есть qlist .Как создать делегаты , расположенные не ввиде списка , а по заданным координатом на экране?
Имеется список указателей на объекты A(унаследован от qobject)Делегаты (у меня разные к примеру круг , квадрат (каждый содержит поле , текст и имеет тип) rect.qml,circle.qml т.д )Согласно типу нужно отобразить нужный делегат (с заранее заданными координатами ) , и отобразить текст .Тип и текст это поля класса A.Как отображать делегаты в qml ,которые нужно расположить не ввиде списка (таблицы)?
Ответы (1 шт):
Сделал небольшой примерчик того, как можно сделать вашу задачу. В качестве элементов модели выступает структура, содержащая тип, координаты и размеры. С помощью указанного типа мы будет определять какой делегат необходимо отрисовать. В QML для этого используется DelegateChooser. Каждый Rectangle в DelegateChoice можно заменить своим объектом. Главное туда передать соответствующие свойства для того чтобы каждый элемент отрисовался по координатам и размерам из модели Модель:
#ifndef MYMODEL_H
#define MYMODEL_H
#include <QAbstractListModel>
#include <QObject>
#include <QList>
class MyModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit MyModel(QObject *parent = nullptr);
enum Roles {
Type = Qt::UserRole + 1,
X,
Y,
Width,
Height
};
// QAbstractItemModel interface
public:
int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
QHash<int, QByteArray> roleNames() const override;
private:
struct ListItem {
int type_;
int x_;
int y_;
int width_;
int height_;
};
QList<ListItem> data_list;
};
#endif // MYMODEL_H
Имплементация модели:
#include "mymodel.h"
MyModel::MyModel(QObject *parent)
: QAbstractListModel(parent)
{
data_list.push_back(ListItem{0, 10, 10, 5, 5});
data_list.push_back(ListItem{1, 50, 50, 10, 10});
data_list.push_back(ListItem{1, 100, 100, 15, 15});
data_list.push_back(ListItem{0, 150, 150, 10, 10});
data_list.push_back(ListItem{1, 200, 200, 10, 10});
}
int MyModel::rowCount(const QModelIndex &parent) const
{
return data_list.size();
}
QVariant MyModel::data(const QModelIndex &index, int role) const
{
if(!index.isValid())
{
return QVariant();
}
const ListItem& data = data_list[index.row()];
switch (role)
{
case Roles::Type: return data.type_;
case Roles::X: return data.x_;
case Roles::Y: return data.y_;
case Roles::Height: return data.height_;
case Roles::Width: return data.width_;
default: return QVariant();
}
}
QHash<int, QByteArray> MyModel::roleNames() const
{
QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
roles[Type] = "Type";
roles[X] = "X";
roles[Y] = "Y";
roles[Height] = "Height";
roles[Width] = "Width";
return roles;
}
QML:
import QtQuick 2.15
import QtQuick.Controls 2.15
import Qt.labs.qmlmodels 1.0
ApplicationWindow {
id: window
width: 640
height: 480
visible: true
title: qsTr("Stack")
Repeater {
anchors.fill: parent
DelegateChooser {
id: chooser
role: "Type"
DelegateChoice { roleValue: 0; Rectangle {x: X; y: Y; width: Width; height: Height; color: "red"}}
DelegateChoice { roleValue: 1; Rectangle {x: X; y: Y; width: Width; height: Height; color: "green"}}
}
model: mymodel
delegate: chooser
}
}
Main:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "mymodel.h"
#include <QQmlContext>
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
MyModel *model = new MyModel();
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.rootContext()->setContextProperty("mymodel", model);
engine.load(url);
return app.exec();
}