I have a file called "SingleTile.qml" with following content
import QtQuick 2.15
Item {
width: 100; height: 100
Rectangle {
anchors.centerIn: parent
color: "green"
}
}
On a button click, i do the following to create an instance of SingleTile.qml
QQmlEngine engine;
QQmlComponent component(&engine,
QUrl::fromLocalFile("SingleTile.qml"));
QQuickItem *object = qobject_cast<QQuickItem*>(component.create());
object->setProperty("color", "blue");
But this does not show any rectangle on the screen with either green or blue color. Why?
CodePudding user response:
Sorry i don't know what your problem is exactly, because you haven't provided enough information about the issue.
But here are some stuff that maybe causing the issue:
QUrl::fromLocalFile creates an absolute path to the given file at you application's location. In your case i would rather just use the constructor with a "qrc:/SingleTile.qml" this will create a relative path to the Qt resource system.
You should be checking for errors after constructing your QQmlComponent by calling "isError" and "errorString".
You need to specify a visual parent for your created item by setting the "parent" property through "setProperty" or "setParentItem", otherwise there is nowhere that the item can be visualized.
CodePudding user response:
Note there are bugs in your SingleTile component. Firstly the green Rectangle { } actually has zero width and height. To correct that bug, you need to change anchors.centerIn: parent
to anchors.fill: parent
. The other problem is the color cannot be changed because the parent Item has no color
property. To fix that you should bubble up that property from your Rectangle with something like a property alias.
//SingleTile.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
Item {
width: 100; height: 100
property alias color: rect.color
Rectangle {
id: rect
anchors.fill: parent
color: "green"
}
}
Do you require to dynamically create your components in c ? If the button click is done in QML, you can handle the dynamic creation and deletion of your components completely in QML.
There is a Qt page that documents the approach https://doc.qt.io/qt-6/qtqml-javascript-dynamicobjectcreation.html
However, if you want to avoid such complexity, you can consider reworking the dynamic creation as a matter of ListModel and delegates as follows. As you add to the ListModel the delegate will instantiate new instance of your component automatically. As you delete from the ListModel, instances of your component will be deleted automatically.
I use this QML online service which demonstrates the dynamic creation and deletion of SingleTile. Since I am using this QML online service it requires me to put everything in one file, so, I have implemented SingleTile as an inline component instead of a separate file.
import QtQuick 2.15
import QtQuick.Controls 2.15
Page {
anchors.fill: parent
component SingleTile: Item {
width: 100; height: 100
property alias color: rect.color
Rectangle {
id: rect
anchors.fill: parent
color: "green"
}
}
Repeater {
model: listModel
delegate: SingleTile {
x: tileX
y: tileY
color: tileColor
Text {
text: "X"
anchors.right: parent.right
color: "white"
MouseArea {
anchors.fill: parent
onClicked: listModel.remove(index)
}
}
}
}
ListModel {
id: listModel
}
Button {
text: qsTr("Create")
onPressed: {
let tileX = Math.floor(Math.random() * parent.width);
let tileY = Math.floor(Math.random() * parent.height);
let tileColor = ["green", "blue"][Math.floor(Math.random() * 2)];
listModel.append( { tileX, tileY, tileColor } );
}
}
}
You can Try it Online!