Change property of items in component from outside
-
hi guys,
question: i want change a item in a component from outside but i cant find a solutuion for that.
example:main.qml
@
Repeater {
model:8
component1 {
...
}
}
@component1.qml
@
component2 {
id: root
property int textWidth: 25
property int displayedHeight: heightInMeterText {
x: 0
y: - font.pixelSize * 0.5
width: root.textWidth
horizontalAlignment: Text.AlignRighttext: displayedHeight + " m"
color: config.scaleItem_TextColor
}
@component2.qml
@
Item {
id: rootproperty QtObject config
property double heightInMeterx: Math.round(config.leftInMeter * config.xPixelPerMeter)
y: Math.round(heightInMeter * config.yPixelPerMeter)Rectangle {
anchors {
left: parent.left
leftMargin: 30
}height: 1
width: config.widthInMeter * config.xPixelPerMeter - anchors.leftMargincolor: config.scaleItem_LineColor
}}
@Now I want to change the width of the rectangle in component2 from my main.qml. How can I access this variable?
My actual solution for that is, to give each component some properties what I can access from outside. But i'm not happy with this, because every time I have to edit the component if I want to change an variable from outside.
Any other ideas to solve that problem?Regards
-
Hi,
You can keep a global property in main.qml. Bind this property to the Component's Width property. So whenever that global property changes the Component's Width will also change. Ofcourse it will also affect other Components since you are using a Repeater but for that you can keep another property in main.qml which will contain the index of the Component, so that you can check it in individual Component whether its Width should change.
-
That is the way I did it. But every time I decide to change an additional property I have to change the components. This i don't want. If there is no other possiblity I will do so. But i hope that QT has a feature what I can use to change the property directly.
-
AFAIK, to change the property directly you will need to find the exact Component which you have loaded through Repeater and it would quite cumbersome.
-
Well it depends upon how you instantiate the Component
For eg if you use Loader to load a Component, you can use "Loader.item":http://doc.qt.io/qt-5/qml-qtquick-loader.html#item-prop to get access to it.
Or if you use createComponent and createObject you can access the properties directly.
@
var component = Qt.createComponent("Button.qml");
if (component.status == Component.Ready) {
var obj = component.createObject(parent, {"x": 100, "y": 100});
console.log(obj.x,obj.y)
}
@For ref. check "here":http://doc.qt.io/qt-5/qml-qtqml-component.html#createObject-method.
-
I didn't instance the components over a function i just use
@
import "components/"
@I don't want change just the compnent property like position width etc.
my component has more like one item (see the example above, componet2.qml)
and now i want access one of this items and change the properties.I checked the loader function and the qt.createComponent but it looks like that they don't fit my needs. Or I'm blind to see it.
At the moment I decided to write the components as a Item in the Repeater and change the property manual. See the example. But I'm not happy with that.
(Identical with the first example just change the width of the rectangle to width: 30)
@
Repeater {
model:12Item { property int textWidth: 25 property int displayedHeight: heightInMeter //property QtObject config property double heightInMeter: ((-2) + ( index * 2 )) x: Math.round(root.config.leftInMeter * config.xPixelPerMeter) y: -Math.round(heightInMeter * config.yPixelPerMeter) Text { x: 0 y: - font.pixelSize * 0.5 width: parent.textWidth horizontalAlignment: Text.AlignRight text: displayedHeight + " m" color: root.config.scaleItem_TextColor } Rectangle { anchors { left: parent.left leftMargin: 30 } height: 1 width: 30 color: root.config.scaleItem_LineColor } }
}
@ -
Well now since we have fallen back to Repeater again, consider the following example similar to yours:
@
import QtQuick 2.4Item {
id: item
width: 200
height: 400Repeater { id: repeater model: 10 Rectangle { x: 0 y: index*40 color: "lightgray" border.color: "gray" width: 200 height: 40 Text { objectName: "obj"+index anchors.centerIn: parent text: "Text" + index } } } MouseArea { anchors.fill: parent onClicked: { for(var a =0; a< item.children.length; a++) if(typeof item.children[a].children[0] !== "undefined") if(item.children[a].children[0].objectName==="obj3") { item.children[a].children[0].text = "Found You" } } }
}
@As I said earlier to get access to Item in a Repeater you will need to find the exact Item (in this case Text element with objectName obj3), and then you can access its properties. But it requires iterating through the objects hierarchy.
Another way as we discussed at the start of the post was to keep the global property and binding to it. -
That's fine. But I think binding to to global property would be the best way. Anyway if you find any other way please post it so that others would too benefit from it.