Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. [Solved] Item::mapToItem(): wrong returned values
Forum Updated to NodeBB v4.3 + New Features

[Solved] Item::mapToItem(): wrong returned values

Scheduled Pinned Locked Moved QML and Qt Quick
9 Posts 4 Posters 10.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • j1eloJ Offline
    j1eloJ Offline
    j1elo
    wrote on last edited by
    #1

    UPDATE 2: Solved. I was using the function in a wrong way!
    Solution: http://qt-project.org/forums/viewreply/114331/


    UPDATE: Read next post for a minimal example code.


    Hi all!
    I'd like to write my very first message in this forum since the acquisition by Digia and creation of the Qt Project.

    My problem is that Item::mapToItem(null, x, y) is giving wrong values. As I'm a beginner about the new Qt Quick 2, and QML in general, it is most probably due to a misuse but I cannot find it.

    A maybe-not-so-minimal working example to show my case follows. It creates a couple of rectangles with a Repeater, and fails at finding the central point for the second one (stored in posX, posY properties). Being squares of size 25, I'd expect the second one to stay at (0, 25), with its center at (0, 37.5), but mapToItem() says that it is placed at (0, 50), so the center calculations go for (0, 67.5) instead.

    I would bet the culprit is the reparenting done to the items, but that's the only way I found to have a clean list of Rectangles: if the Repeater was placed inside the Column, as most Qt examples show, then the Column's children would include that Repeater, which is not nice for code abstraction (other parts of the code shouldn't have to deal with that detail).

    @
    import QtQuick 2.0

    Item {
    id: root
    width: buttonSize
    height: (2 * buttonCount + 1) * buttonSize

    property int buttonCount: 2
    property real buttonSize: 25
    property alias buttons: container.children
    
    Component.onCompleted: {
        console.log("root: onCompleted")
        for (var i = 0; i < buttons.length; ++i) {
            console.log("root:", buttons[i].buttonId, "x", buttons[i].x, "y", buttons[i].y)
            buttons[i].posUpdate()
        }
    }
    
    Column {
        id: container
        anchors {
            fill: parent
    

    // topMargin: buttonSize
    }
    // spacing: buttonSize
    }

    Repeater {
        model: buttonCount
    
        Item {
            // Use a dummy Item to wrap our Socket element.
            // The wrapper will become child of the Repeater's parent,
            // while the Socket will be reparented to our container.
            id: wrapper
    
            Rectangle {
                id: button
                width: buttonSize; height: buttonSize; radius: buttonSize
                color: "red"
    
                property string buttonId: "button_" + index
                property real posX
                property real posY
    
                function posUpdate() {
                    console.log("button: posUpdate", buttonId, "button.x", x, "button.y", y, "mapToItem().x", mapToItem(null, x, y).x, "mapToItem().y", mapToItem(null, x, y).y)
                    posX = button.mapToItem(null, x, y).x + (buttonSize / 2.0)
                    posY = button.mapToItem(null, x, y).y + (buttonSize / 2.0)
                    console.log("button: posUpdate", buttonId, "posX", posX, "posY", posY)
                }
    
                Component.onCompleted: {
                    parent = container
                }
            }
        }
    }
    

    }
    @

    Any help would be appreciated :-)

    1 Reply Last reply
    0
    • j1eloJ Offline
      j1eloJ Offline
      j1elo
      wrote on last edited by
      #2

      OK I have a new, minimal example to show this problem:

      @
      import QtQuick 2.0

      Item {
      id: window
      width: 25; height: 50

      Rectangle {
          id: button_1
          x: 0; y: 0
          width: 25; height: 25
          color: "red"
      
          Component.onCompleted: {
              var obj = mapToItem(null, x, y)
              console.log("[button_1]", "x:", x, "y:", y, "mapToItem().x:", obj.x, "mapToItem().y", obj.y)
          }
      }
      
      Rectangle {
          id: button_2
          x: 0; y: 25
          width: 25; height: 25
          color: "pink"
      
          Component.onCompleted: {
              var obj = mapToItem(null, x, y)
              console.log("[button_2]", "x:", x, "y:", y, "mapToItem().x:", obj.x, "mapToItem().y", obj.y)
          }
      }
      

      }
      @

      Expected output:
      @[button_2] x: 0 y: 25 mapToItem().x: 0 mapToItem().y 25@

      Obtained output:
      @[button_2] x: 0 y: 25 mapToItem().x: 0 mapToItem().y 50@

      1 Reply Last reply
      0
      • T Offline
        T Offline
        tzander
        wrote on last edited by
        #3

        Responding to a weird issue, that may even be the core problem;
        @
        "if the Repeater was placed inside the Column [] then the Column’s children would include that Repeater
        which is not nice for code abstraction (other parts of the code shouldn’t have to deal with
        that detail)."
        @

        This looks weird, the idea behind QML and scenegraphs in general is that this kind of details are irrelevant to the rest of the codebase.
        Just because there is a repeater in between should have zero effect on other code.

        You use the name (id: foo) of an element.

        Maybe you are trying to fetch an item from a C++ code using the QObject:child() method, I would strongly suggest you do not do that ;)

        Maybe you can explain exactly what the problem is that you ran into that made you reparent? Its likely that its the one that should be solved first.

        1 Reply Last reply
        0
        • j1eloJ Offline
          j1eloJ Offline
          j1elo
          wrote on last edited by
          #4

          Note that in my second post I included a minimal example which shows the same wrong results on Item::mapToItem(), without any reparenting.

          Replying to your question:

          My project is pure QML + JavaScript so far; I just want to process a list of items all in the same way, which means all must be of the same type.

          I'm using a Canvas item which paints lines; these lines are parametrized by properties of some items, previously instantiated inside a Column. Ideally, the JS code on the Canvas::onPaint() method would use a "for" loop over all of the Colum's children, but that approach doesn't work because one of the children is a Repeater, thus not being of the expected type and not having the expected properties.

          Maybe I'm not doing this the "QML way"? But I didn't find a better way...

          1 Reply Last reply
          0
          • C Offline
            C Offline
            chrisadams
            wrote on last edited by
            #5

            Passing in null as the first parameter of mapToItem is currently broken. There are some changes in codereview to address this issue, but currently the script engine returned is null. In the future, this function should map it from top left of the top-level application window; currently the behaviour is undefined.

            Cheers,
            Chris.

            1 Reply Last reply
            0
            • j1eloJ Offline
              j1eloJ Offline
              j1elo
              wrote on last edited by
              #6

              I assumed that there was no need for a bug report because this issue is already a work in progress, but after searching in the Qt bugreports site for "mapToItem" and "mapFromItem", I cannot find any proper report about this issue.

              So I'm adding one for being able to track this bug.

              Thank you all for the ideas and chrisadams for the explanation

              1 Reply Last reply
              0
              • ? Offline
                ? Offline
                A Former User
                wrote on last edited by
                #7

                Hi,

                parameters x,y are not required in maptoItem. Just put it as 0 for both x and y and then try.

                Regards
                ansif

                1 Reply Last reply
                0
                • j1eloJ Offline
                  j1eloJ Offline
                  j1elo
                  wrote on last edited by
                  #8

                  [quote author="ansifpi" date="1360752153"]Hi,

                  parameters x,y are not required in maptoItem. Just put it as 0 for both x and y and then try.

                  Regards
                  ansif [/quote]

                  Thank you very much!!
                  Thanks to this comment I realized that the mapToItem() function is working properly, it's just that I was misusing it in my examples!! The cause of the problem is a conceptual error.

                  Note that in both examples I was using
                  @mapToItem(null, x, y)@
                  which would map to the Window the point (x, y) inside the rectangle. In my second example, the point (0, 25) inside of the second rectangle would effectively correspond to the point (0, 50) in the Window.

                  Correct way of using the function in my sample would be:
                  @mapToItem(null, 0, 0)@

                  And for my specific need of mapping the center point:
                  @mapToItem(null, width / 2.0, height / 2.0)@

                  Thanks everybody for the help.

                  1 Reply Last reply
                  0
                  • ? Offline
                    ? Offline
                    A Former User
                    wrote on last edited by
                    #9

                    Good luck!!!!!!!!!

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved