У меня есть qlist .Как создать делегаты , расположенные не ввиде списка , а по заданным координатом на экране?

Имеется список указателей на объекты A(унаследован от qobject)Делегаты (у меня разные к примеру круг , квадрат (каждый содержит поле , текст и имеет тип) rect.qml,circle.qml т.д )Согласно типу нужно отобразить нужный делегат (с заранее заданными координатами ) , и отобразить текст .Тип и текст это поля класса A.Как отображать делегаты в qml ,которые нужно расположить не ввиде списка (таблицы)?


Ответы (1 шт):

Автор решения: Rafael

Сделал небольшой примерчик того, как можно сделать вашу задачу. В качестве элементов модели выступает структура, содержащая тип, координаты и размеры. С помощью указанного типа мы будет определять какой делегат необходимо отрисовать. В 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();
}
→ Ссылка