Brykyz
Brykyz

Reputation: 657

Drawing multiple rectangles into image in QML

I am trying to draw rectangles into QML. Data, which contains info about those rectangles, looks like this:

Data are stored in array and each item in array represents one rectangle. I am looking for best (or at least a good) way to draw those rectangles.

Which component of QML should I use?

class.h

class MyClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QList<structure> list READ list NOTIFY listChanged)
    public:
        QList<structure> list() const { return list_; }
    signals:
        listChanged();
    private:
        QList<structure> list_;
}

repeater.qml

Repeater {
    model: 2 
    delegate: Rectangle{
        width: model.list.width
        height: model.list.height
        x: model.list.x
        y:  model.list.y
        color: "red"
    }
}

Upvotes: 3

Views: 2383

Answers (1)

eyllanesc
eyllanesc

Reputation: 243907

It is not necessary to create a QObject, just a QVariantList that stores the QRect is enough. On the other hand the model that you have to pass is just the list of QRect, to access each QRect in the delegate you must use modelData.

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include <QRect>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QVariantList rectlist;
    rectlist<< QRect{50, 30, 100, 100}
            << QRect{200, 20, 30, 30}
            <<QRect{300, 300, 200, 33}
           <<QRect{400, 23, 44, 55};

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("rectlist", rectlist);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Repeater {
        model: rectlist
        delegate: Rectangle{
            x: modelData.x
            y: modelData.y
            width: modelData.width
            height: modelData.height
            color: "red"
        }
    }    
}

enter image description here


Update:

main.cpp

#include <QColor>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include <QRect>

struct Data
{
    Q_GADGET
    Q_PROPERTY(QRect rect MEMBER rect)
    Q_PROPERTY(QString text MEMBER text)
    Q_PROPERTY(QColor color MEMBER color)
public:
    QRect rect;
    QString text;
    QColor color;
    Data(const QRect& rect= QRect(), const QString& text="", const QColor& color = QColor(Qt::transparent)){
        this->rect = rect;
        this->text = text;
        this->color = color;
    }
};
Q_DECLARE_METATYPE(Data)

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);
    QVariantList rectlist;
    rectlist <<QVariant::fromValue( Data{ QRect{50, 30, 100, 100}, "text1", Qt::red});
    rectlist <<QVariant::fromValue( Data{ QRect{200, 20, 30, 30 }, "text2", QColor("blue")});
    rectlist <<QVariant::fromValue( Data{ QRect{300, 300, 200,33}, "text3", QColor(0, 200, 0)});
    rectlist <<QVariant::fromValue( Data{ QRect{400, 23, 44, 55 }, "text4"});

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("rectlist", rectlist);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

#include "main.moc"

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Repeater {
        model: rectlist
        delegate: Rectangle{
            x: modelData.rect.x
            y: modelData.rect.y
            width: modelData.rect.width
            height: modelData.rect.height
            color: modelData.color
            Text{
                anchors.centerIn: parent
                text: modelData.text
            }
        }
    }
}

enter image description here

Upvotes: 6

Related Questions