Why does mapToItem return a QVariantMap instead of QPoint?



  • An inconvenience I stumbled upon - it is not possible to assign the result of mapToItem to a point property. That just doesn't seem like a very good design intent. Instead of:

    @p = mapToItem(null, mouseX, mouseY)@

    I have to assign each component individually:

    @p.x = mapToItem(null, mouseX, mouseY).x
    p.y = mapToItem(null, mouseX, mouseY).y@

    which also has to call the mapToItem function twice.

    I also noticed that QML elements really don't have the concept of position build in, only the individual components of it. Which means more bindings and more assignment to move elements by their individual position components.



  • You could always do

    @
    var pos = mapToItem(null, mouseX, mouseY);
    p.x = pos.x;
    p.y = pos.y;
    @
    to prevent calling the method twice ;)

    And it is best to always try to stick to using anchors to align elements to each other, this is faster than bindings and also pretty readable.



  • There are plenty of scenarios where items need to be free and movable by the user, anchoring is applicable to user interface graphics but not to program element graphics.

    It would make much more sense and it would be much more flexible if there was a position property as well on top of its individual components. Especially considering it is just a matter of accessors, no extra data needs to be stored.

    I agree it would be bad if individual components were children of the position properti, a.k.a. you have to go "pos.x:" as is it is with anchors, but this can be avoided.



  • How would you avoid exposing the components as subproperties - and why would you want to?

    Would the "pos" property just be completely "opaque" to JavaScript / QML code? If so, then it becomes useless in bindings. If not, then it would need to be exposed as a value-type (so that binding expressions and signal handlers can do pos.x if they wish) - and as soon as you're using value-types you're incurring a fairly large amount of overhead for absolutely every position-related call. I'd be interested in seeing benchmarks of two animations, one which animates an int property to which another int property is bound, and one which animates an int property to which a value-type subproperty (eg, the x component of a vector3d) is bound. I actually haven't benchmarked this, as far as I can remember, but I would imagine that the second one would take significantly more CPU.

    Cheers,
    Chris.



  • bq. I actually haven’t benchmarked this, as far as I can remember, but I would imagine that the second one would take significantly more CPU.

    Without nitpicking, purely out of technical interest, why? I do seem to have some trouble figuring out what is exactly in your mind in this regard.



  • Limiting it to just dynamic properties (ie, vmemo data properties) since this simplifies the comparison:

    Purely due to the write semantics of value types. The value type "wrapper" (actually, wrapper is a terrible name, it should be "agent" or something, I guess) takes the subproperty value, composes a "complete" value from the original complete value modified with the subproperty value, and then writes the entire new complete value back to the (qvariant storage type) property cell.

    There's more work being done there, than for most primitive types (which are actually still stored to a qvariant storage cell, in the case of dynamic properties, but there's no composition step).

    So I benchmarked this, and found out that the actual difference wasn't nearly as much as I was expecting:

    @
    import QtQuick 2.0
    Item {
    property int changingOne
    property int changingTwo
    property int boundOne: changingOne
    property vector3d v3
    v3 {
    x: changingTwo
    }

    Component.onCompleted: {
        var i
    
        console.time("bound int evaluation")
        for (i = 0; i < 1000; i++) {
            changingOne = i
        }
        console.timeEnd("bound int evaluation")
    
        console.time("bound v3 evaluation")
        for (i = 0; i < 1000; i++) {
            changingTwo = i
        }
        console.timeEnd("bound v3 evaluation")
    }
    

    }
    @

    On my system, I'm getting 41 ms for the first, and 44 ms for the second, on average.
    That's... not nearly as much difference as I expected to see, to be honest. Interesting!

    Cheers,
    Chris.



  • I get between 0 and 1 msec arbitrarily, but boosting the number of iterations to 100k the difference is almost twice: ~47 msec for int, ~77 msec for v3.

    However I got almost identical results (49 vs 54) for a custom element of type Position that exposes both a pos property as well as individual x and y components, however x and y are non-STORED properties but derived from pos. Which was sort of my idea - that they are not nested inside of pos but available on the same level. No extra hop.

    Of course, since I implement Position as an element there is some overhead, it maybe possible to reduce that small performance difference further.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.