I want to draw many Rectangular's inside a QML. The coordinates for Rectangulars (x,y) will be calculated inside C++, and need to be passed to QML.
I tried to look for ListView or Column or Row elements (with Repeater), but non of this seems to solve the problem, because the elements are arranged like in 'tables'... I faced the lack of information on the web examples on such case.
To be more specific:
1. How to pass many coordinates for my Rectangular's to QML? (what data structure)
2. What mechanism should I use to display them?
Creating a Component Dynamically To dynamically load a component defined in a QML file, call the Qt. createComponent() function in the Qt object. This function takes the URL of the QML file as its only argument and creates a Component object from this URL.
Emitted after component "startup" has completed. This can be used to execute script code at startup, once the full QML environment has been established. The corresponding handler is onCompleted. It can be declared on any object. The order of running the onCompleted handlers is undefined.
A QML object type is a type from which a QML object can be instantiated. In syntactic terms, a QML object type is one which can be used to declare an object by specifying the type name followed by a set of curly braces that encompasses the attributes of that object.
Unlike an ordinary property definition, which allocates a new, unique storage space for the property, a property alias connects the newly declared property (called the aliasing property) as a direct reference to an existing property (the aliased property).
You could simply:
import QtQuick 2.0
Rectangle {
id: root
height: 500
width: 500
property string sc: 'import QtQuick 2.0; Rectangle {width: 20; height: 20; color: "red"; Component.onCompleted: {x = Math.random() * parent.width; y = Math.random() * parent.height;}}'
Component.onCompleted: {
for (var i = 0; i < 10; ++i) Qt.createQmlObject(sc, root, 'obj' + i);
}
}
This code will create the specified number of rectangles and position them randomly over the parent rectangle.
If generating the position in C++ is a necessity, you will have to create a custom C++ element, here is a basic example:
class Positioner : public QObject
{
Q_OBJECT
public:
explicit Positioner(QObject *parent = 0) : QObject(parent) {}
public slots:
QPointF getPosition() {
return QPoint(qrand() % 500, qrand() % 500);
}
};
Register it in main.cpp:
qmlRegisterType<Positioner>("TestComponent", 1, 0, "Positioner");
And finally use it, this time we use the Positioner's getPosition()
C++ slot:
import QtQuick 2.0
import TestComponent 1.0
Rectangle {
id: root
height: 500
width: 500
Positioner {id: myPositioner}
property string sc: 'import QtQuick 2.0; Rectangle {width: 20; height: 20; color: "red"; Component.onCompleted: {var pos = myPositioner.getPosition(); x = pos.x; y = pos.y;}}'
Component.onCompleted: {
for (var i = 0; i < 10; ++i) Qt.createQmlObject(sc, root, 'obj' + i);
}
}
You can also use an existing QML file instead of a string, which is a little more convenient, since you get autocomplete. That would be your TestItem component and just for fun, its instances will delete themselves when clicked:
import QtQuick 2.0
Rectangle {
width: 100
height: 100
color: "black"
MouseArea {
anchors.fill: parent
onClicked: parent.destroy()
}
Component.onCompleted: {
var pos = myPositioner.getPosition()
x = pos.x
y = pos.y
}
}
And in your main QML file you instantiate it:
var component = Qt.createComponent("TestItem.qml")
component.createObject(root)
In case you don't want to instantiate a Positioner in QML and instead instantiate and use a single object in QML, you can do the following (in main.cpp):
Positioner p;
view.rootContext()->setContextProperty("sPositioner", &p);
And use in QML:
var pos = sPositioner.getPosition()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With