[Qt-qml] QML and binding loop problem

michael.brasser at nokia.com michael.brasser at nokia.com
Thu Nov 18 04:00:31 CET 2010


Hi,

It's probably easiest to look at a simplified example:

 Rectangle {
    id: rect
    function myWidth() {
        return rect.width
    }
    height: myWidth()
}

When the engine analyses the binding for height (i.e. myWidth()), it keeps track of the fact that rect.width was used in the binding (inside the function), and adds a dependency there -- whenever rect.width changes, it will update the binding. But if we modify the function to:

 Rectangle {
    id: rect
    function myWidth() {
        rect.width = 100;
        return rect.width
    }
    height: myWidth()
}

The engine still adds a dependency on rect.width, but in this case we manipulate that same property in the function itself, which triggers the engine to update the binding whenever the function is run. Component.onCompleted works because it assigns a value, rather than setting up a binding. I'm not sure whether it makes sense to try and address this in the engine somehow (maybe some sort of flag you could set in the function that told the engine to ignore dependancies?) -- for now at least you'll need at least one "imperative" step in the chain to prevent the loop errors (another option moving forward is for us to make binding loop detection more relaxed; and/or provide a way to turn off the warnings).

Regards,
Michael

On 16/11/2010, at 11:43 PM, ext Valentine Silvansky wrote:

> Hi all! I've got some problem...
> 
> I have to make a elide for multiline text. Here is the code I wrote:
> 
> <pre>
> Text {
> 	id: tempText
> 	visible: false
> 	width: parent.width
> 	wrapMode: Text.WordWrap
> 	function elideMultiline(etext, pointSize, linesCount) {
> 		console.log("elideMultiline: " + etext + " " + pointSize + " " + linesCount)
> 		tempText.font.pointSize = pointSize
> 		var l = etext.length
> 		var s = "";
> 		for (var i = 0; i < linesCount; i++) {
> 			s += "W";
> 			if (i < linesCount - 1)
> 				s += "\n"
> 		}
> 		tempText.text = s
> 		console.log("s = " + s)
> 		var maxHeight = tempText.paintedHeight
> 		tempText.text = etext
> 		while (tempText.paintedHeight > maxHeight) {
> 			tempText.text = etext.substring(0, l--) + "..."
> 		}
> 		return tempText.text
> 	}
> }
> Text {
> 	id: longText
> 	width: parent.width
> 	wrapMode: Text.WordWrap
> 	font.pointSize: 16
> 	text: tempText.elideMultiline("my very-very-very-very and very long
> text with a lot of words in it and which i want to be correctly
> elided", font.pointSize, 2)
> }</pre>
> 
> And when running my qml I've got this output:
> 
> QML Text: Binding loop detected for property "text"
> 
> The resulting qml output is ok, function works as expected, but i've
> got tons of console output messages...
> What's the problem of this code?
> 
> PS: if I use Component.onCompleted: { text = "....." } no messages are printed
> _______________________________________________
> Qt-qml mailing list
> Qt-qml at trolltech.com
> http://lists.trolltech.com/mailman/listinfo/qt-qml





More information about the Qt-qml mailing list