Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    [Solved] QML Draw order

    QML and Qt Quick
    4
    7
    13476
    Loading More Posts
    • 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.
    • T
      tedmiddleton last edited by

      How does QML draw order work, especially given that QML is declarative rather than imperative? If I have this code:

      @
      import QtQuick 1.1

      Rectangle {
      id: outerRect
      color: "red"
      Text {
      anchors.centerIn: parent
      text: "outerRect"
      }
      x: 0; y: 0; width: 250; height: 150

      Rectangle {
          id: midLevelRect1
          color: "blue"
          Text {
              anchors.centerIn: parent
              text: "midLevelRect1"
          }
          x: 10; y: 10; width: 75; height: 75
      
          Rectangle {
              id: innerRect
              color: "green"
              Text {
                  anchors.centerIn: parent
                  text: "innerRect"
              }
              x: 50; y: 50; width: 75; height: 75
          }
      }
      
      Rectangle {
          id: midLevelRect2
          color: "yellow"
          Text {
              anchors.centerIn: parent
              text: "midLevelRect2"
          }
      
          x: 100; y: 10; width: 75; height: 75
      }
      

      }

      @

      I kind of expected (or hoped) to see this:

      !http://i.imgur.com/GVEl0Lz.png(Green is over - like a tooltip)!

      But what I actually see is this:

      !http://i.imgur.com/g2ctf6R.png(Green is under - like... ?)!

      Its occurred to me that in a way, declarative syntax doesn't provide a really great way to structure draw order. Most functional languages don't necessarily require a particular applicative order and draw order here is almost sort of a side-effect of the applicative ordering that the QML runtime has been designed around. How does QML do this? It's pretty clear that behind the scenes the qml runtime is evaluating the object tree in a simple and strict dfs order - is this necessarily true all the time?

      More to the point, I'm trying to implement something like tooltips. With those screen shots you can imagine the green rectangle being a tooltip and the blue and yellow rectangles are widgets/QWidgets/QML Items. To get the tooltip to display on top of everything, including adjacent widgets, I ended up having to declare it under the common root - in this case I had to declare innerRect underneath outerRect rather than midLevelRect1, even though the tool tip really sort of belongs to midLevelRect1. Where this really causes problems is with view delegates in the qml data model - like having a tooltip for an item in a ListView.

      I would have thought that setting innerRect's z property to some large number would draw it over midLevelRect2, but it doesn't. If this isn't what z is for, why do we even have it in Item?

      I'm using QtQuick 1.0 in Qt 4.8.4 on Windows, but 4.8.4 on OSX behaves identically. Can anyone fill me in?

      1 Reply Last reply Reply Quote 1
      • B
        bjanuario last edited by

        it's because u're anchor green on blue and isolated the yellow ...
        try to anchor green on yellow

        1 Reply Last reply Reply Quote 0
        • T
          tedmiddleton last edited by

          I think you've misunderstood, or perhaps I haven't explained this well enough. The green rectangle is a tool tip for the blue widget, not the yellow widget. Why would I parent it under the yellow widget if it's the blue widget's tooltip? That would be even crazier than having to parent it under the common parent (the red background rectangle), which is what I ended up having to do.

          Having to hack the tooltip under the common parent to get draw order right is ugly because it works against code re-use and encapsulation. Because of this issue, as far as the knowledge that I have right now goes, I wouldn't be able to make a reusable widget that draws its own tooltips.

          1 Reply Last reply Reply Quote 0
          • J
            JapieKrekel last edited by

            Drawing order in QML is from the first declared element in the QML to last. Every following item will be on top of that Item. Same goes for items within items. This is not so strange, looking for instance to Photoshop and layers the same order applies.

            You can use the z: property to 'force' it to be rendered in another order. Default z=0, making the 'tooltip' item for instance z: 100 will for sure draw it on top.

            The reason it does not happen in your case is that the green rectangle is a child of the blue rectangle. The z property applies to the drawing order of siblings. So changing the z of the green rectangle will move it on top of other child elements of the blue rectangle, but there aren't any.

            Moving the Green rectangle up one level giving it the same parent as the other rectangles, but keeping the same element order, the z property can do its magic.
            @
            import QtQuick 1.1

            Rectangle {
            id: outerRect
            color: "red"
            Text {
            anchors.centerIn: parent
            text: "outerRect"
            }
            x: 0; y: 0; width: 250; height: 150

            Rectangle {
                id: midLevelRect1
                color: "blue"
                Text {
                    anchors.centerIn: parent
                    text: "midLevelRect1"
                }
                x: 10; y: 10; width: 75; height: 75
            
            
            }
            Rectangle {
                id: innerRect
                color: "green"
                Text {
                    anchors.centerIn: parent
                    text: "innerRect"
                }
                x: 50; y: 50; width: 75; height: 75; z: 100
            }
            
            Rectangle {
                id: midLevelRect2
                color: "yellow"
                Text {
                    anchors.centerIn: parent
                    text: "midLevelRect2"
                }
            
                x: 100; y: 10; width: 75; height: 75
            }
            

            }
            @

            1 Reply Last reply Reply Quote 0
            • T
              tedmiddleton last edited by

              [quote author="JapieKrekel" date="1370178928"]Drawing order in QML is from the first declared element in the QML to last. Every following item will be on top of that Item. Same goes for items within items. This is not so strange, looking for instance to Photoshop and layers the same order applies.
              [/quote]

              Ok - that makes sense.

              [quote author="JapieKrekel" date="1370178928"]
              You can use the z: property to 'force' it to be rendered in another order. Default z=0, making the 'tooltip' item for instance z: 100 will for sure draw it on top.

              The reason it does not happen in your case is that the green rectangle is a child of the blue rectangle. The z property applies to the drawing order of siblings.
              [/quote]

              Now this is what's really strange in my opinion. It almost seems like this property should be called 'siblingZ' or 'localZ', not simply 'z'. When I see that 'z' parameter, I'm thinking that this controls more than a sibling-draw-order hack - that it represents a global z draw order. If they're not going to give us a scene-global draw sort with the 'z' property, it would just be better not to call it 'z' at all. Everyone here at my work that's using QML who has tried to use 'z' to change the draw order has been surprised. With the name 'z', it really violates the 'principle of least astonishment'

              [quote author="JapieKrekel" date="1370178928"]
              So changing the z of the green rectangle will move it on top of other child elements of the blue rectangle, but there aren't any.

              Moving the Green rectangle up one level giving it the same parent as the other rectangles, but keeping the same element order, the z property can do its magic.
              [/quote]

              Thanks for the explanation - the machinery at work is a bit easier to understand now.

              1 Reply Last reply Reply Quote 0
              • J
                JapieKrekel last edited by

                Well see z as 'bring-to-front' as in photoshop. Excact same behavior, an object from a layer that is below another layer, will never go totally in front, ony within that layer.

                Glad to help, if the topic is solved, please mark it as such.

                1 Reply Last reply Reply Quote 0
                • M
                  Muhammad last edited by

                  [quote author="tedmiddleton" date="1370140219"]
                  Having to hack the tooltip under the common parent to get draw order right is ugly because it works against code re-use and encapsulation. Because of this issue, as far as the knowledge that I have right now goes, I wouldn't be able to make a reusable widget that draws its own tooltips.
                  [/quote]

                  I have the same problem as you, and I was looking for a solution without breaking the encapsulation rules, if you got any please let me know.
                  Thanks

                  I don't have endpoint, I just have Checkpoints.

                  1 Reply Last reply Reply Quote 1
                  • First post
                    Last post