Solved Design Rectangle/Button in QML using XML
-
I want to design a rectangle/button using QML and XML. What all information i can keep in QML and what i can keep in XML?
If it is possible please suggest some example. -
hi @JasmineSethi
i'm not sure i understand your question very well but this is a simple example where i create rectangle in my QML code using properties read from XML filerecs.xml
<?xml version="1.0" encoding="UTF-8"?> <table name="rectangle"> <column name="x">150</column> <column name="y">150</column> <column name="height">60</column> <column name="width">60</column> <column name="color">red</column> <column name="radius">10</column> </table>
Rec.qml
import QtQuick 2.0 Rectangle { }
main.qml
import QtQuick 2.9 import QtQuick.Window 2.2 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import QtQuick.XmlListModel 2.0 ApplicationWindow { visible: true width: 640 height: 480 id: appWindow XmlListModel { id: imodel source: "qrc:/recs.xml" query: "/table/column" XmlRole { name: "placeholderTxt"; query: "string(@name)" } XmlRole { name: "val"; query: "string()" } } Button{ anchors.top:parent.top anchors.horizontalCenter: parent.horizontalCenter onClicked: createSpriteObjects() text:"construct rectangle" } // JS functions to create Component dynamically see : http://doc.qt.io/qt-5/qtqml-javascript-dynamicobjectcreation.html property variant component; property variant sprite; function createSpriteObjects() { component = Qt.createComponent("Rec.qml"); if (component.status === Component.Ready) finishCreation(); else component.statusChanged.connect(finishCreation); } function finishCreation() { if (component.status === Component.Ready) { // reading property values from XmlListModel object var x = imodel.get(0).val var y = imodel.get(1).val var ht = imodel.get(2).val var wh = imodel.get(3).val var clr = imodel.get(4).val var rds = imodel.get(5).val sprite = component.createObject(appWindow, { "x": x, "y": y, "height" :ht, "width" : wh, "color" : clr, "radius" : rds }); if (sprite === null) { // Error Handling console.log("Error creating object"); } } else if (component.status === Component.Error) { // Error Handling console.log("Error loading component:", component.errorString()); } } }
-
@LeLev Thanks a lot. Your solution is helpful.
-
@LeLev
I want to design something like this using XML and QML. How to add more than one rectangle in xml?
-
Did you try copy-pasting the same rectangle information again in xml, try getting the values ? Try to get the values like this. Once you get the values, you can create the rectangle object like component.createObject(..) & set the values.
-
@LeLev Awesome
-
@Bhushan_Sure yes Qt is
-
@dheerendra , @LeLev
i wrote the code like this. But output is blank. Not getting what mistake i am doing?
recs.xml
<?xml version="1.0" encoding="UTF-8"?>
<table name="rectangle">
<!--<column name="x1">150</column>
<column name="y1">150</column>
<column name="height1">60</column>
<column name="width1">60</column>
<column name="color1">red</column>
<column name="radius1">10</column>--><column name="x2">200</column>
<column name="y2">200</column>
<column name="height2">60</column>
<column name="width2">60</column>
<column name="color2">pink</column>
<column name="radius2">10</column>
</table>main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
import QtQuick.XmlListModel 2.0ApplicationWindow {
visible: true
width: Screen.width
height: Screen.height
id: appWindowXmlListModel { id: imodel source: "/recs.xml" query: "/table/column" XmlRole { name: "placeholderTxt"; query: "string(@name)" } XmlRole { name: "val"; query: "string()" } } Button{ anchors.top:parent.top anchors.horizontalCenter: parent.horizontalCenter onClicked: createSpriteObjects() text:"construct rectangle" } property variant component; property variant sprite; function createSpriteObjects() { component = Qt.createComponent("Rec.qml"); if (component.status === Component.Ready) finishCreation(); else component.statusChanged.connect(finishCreation); } function finishCreation() { if (component.status === Component.Ready) { // reading property values from XmlListModel object
// var x1 = imodel.get(0).val
// var y1 = imodel.get(1).val
// var ht1 = imodel.get(2).val
// var wh1 = imodel.get(3).val
// var clr1 = imodel.get(4).val
// var rds1 = imodel.get(5).valvar x2 = imodel.get(0).val var y2 = imodel.get(1).val var ht2 = imodel.get(2).val var wh2 = imodel.get(3).val var clr2 = imodel.get(4).val var rds2 = imodel.get(5).val sprite = component.createObject(appWindow, {
// "x1": x1,
// "y1": y1,
// "height1" :ht1,
// "width1" : wh1,
// "color1" : clr1,
// "radius1" : rds1,"x2": x2, "y2": y2, "height2" :ht2, "width2" : wh2, "color2" : clr2, "radius2" : rds2 }); if (sprite === null) { // Error Handling console.log("Error creating object"); } } else if (component.status === Component.Error) { // Error Handling console.log("Error loading component:", component.errorString()); } }
}
-
Did you try to read the contents of the model & print it ? Did you look at how XmlListModel works ?
-
@JasmineSethi
Rectangle has no properties called : x2 ,y2, height2 ...component.createObject(appWindow, { "x2": x2, //sould be "x" not "x2" "y2": y2, // "y " not "y2" "height2" :ht2, // "height" "width2" : wh2, "color2" : clr2, "radius2" : rds2 });
-
@LeLev i tried the way u said but still m not able to display two rectangles "red" and "pink" at the same time.
-
@LeLev
recs.xml looks like this
<?xml version="1.0" encoding="UTF-8"?>
<table name="rectangle">
<column name="x">150</column>
<column name="y">150</column>
<column name="height">60</column>
<column name="width">60</column>
<column name="color">red</column>
<column name="radius">10</column><column name="x">300</column>
<column name="y">300</column>
<column name="height">60</column>
<column name="width">60</column>
<column name="color">pink</column>
<column name="radius">10</column>
</table>main. qml looks like this
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
import QtQuick.XmlListModel 2.0ApplicationWindow {
visible: true
width: Screen.width
height: Screen.height
id: appWindowXmlListModel { id: imodel source: "/recs.xml" query: "/table/column" XmlRole { name: "placeholderTxt"; query: "string(@name)" } XmlRole { name: "val"; query: "string()" } } Button{ anchors.top:parent.top anchors.horizontalCenter: parent.horizontalCenter onClicked: createSpriteObjects() text:"construct rectangle" } // JS functions to create Component dynamically see : http://doc.qt.io/qt-5/qtqml-javascript-dynamicobjectcreation.html property variant component; property variant sprite; function createSpriteObjects() { component = Qt.createComponent("Rec.qml"); if (component.status === Component.Ready) finishCreation(); else component.statusChanged.connect(finishCreation); } function finishCreation() { if (component.status === Component.Ready) { // reading property values from XmlListModel object var x1 = imodel.get(0).val var y1 = imodel.get(1).val var ht1 = imodel.get(2).val var wh1 = imodel.get(3).val var clr1 = imodel.get(4).val var rds1 = imodel.get(5).val var x2 = imodel.get(6).val var y2 = imodel.get(7).val var ht2 = imodel.get(8).val var wh2 = imodel.get(9).val var clr2 = imodel.get(10).val var rds2 = imodel.get(11).val sprite = component.createObject(appWindow, { "x": x1, "y": y1, "height" :ht1, "width" : wh1, "color" : clr1, "radius" : rds1, "x": x2, "y": y2, "height" :ht2, "width" : wh2, "color" : clr2, "radius" : rds2 }); if (sprite === null) { // Error Handling console.log("Error creating object"); } } else if (component.status === Component.Error) { // Error Handling console.log("Error loading component:", component.errorString()); } }
}
-
sprite = component.createObject(appWindow, { "x": x1, "y": y1, "height" :ht1, "width" : wh1, "color" : clr1, "radius" : rds1, "x": x2, "y": y2, "height" :ht2, "width" : wh2, "color" : clr2, "radius" : rds2 });
you are creating only one object here,
you set x,y,height,width properties and then you are re-setting them on the same object. Please create 2 objects