SlapmyFace
SlapmyFace

Reputation: 1

QML: Show object over non siblings

I have a somehow very hard to solve problem in my QML code. I will summarize it the best I can since it is very long code..

I write a color picker qml file that is called when the user wants to pick a color. This is done in a big rectangle with little rectangles in it evenly distributed that have flat colors to choose from.

I have a parent rectangle, 1 outer repeater and nested in this repeater is another inner repeater that creates little rectangle in a row. The outer repeater places the inner repeaters under another so it fills the rectangle with little rectangles fully, preferably with different colors.

Every little rectangle also has a function that highlights itself with an animation. This animation is a circle that gets bigger than the rectangle itself. This is done so when the user clicks a color from e.g. a color history on the right, it should highlight the corresponding colors rectangle if is there.

Now, the problem: No matter what z values I use, this animation won't show above the other rectangles. It will get blocked by neighboring rectangles. I have researched and it seems that z values don't account for non siblings, just for all items in a single parent.

Here's some code that leaves out all the unnecessary junk. To note is that every rectangle has its own animation and mousearea.

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    color: 'black'
    width: 640
    height: 480
    title: qsTr("Hello World")

    Rectangle {
    id: parentRectangle

    width: 400
    height: 400

    property int numberOfBoxesInARow: 5
    property int numberOfBoxesInAColumn: 5

       Repeater {
          id: outerRepeater

          model: parentRectangle.numberOfBoxesInARow

          Repeater {
             id: innerRepeater
             model: parentRectangle.numberOfBoxesInAColumn

             y: parentRectangle.height / parentRectangle.numberOfBoxesInAColumn * outerIndex
             x: 0

             height: parent.height / parentRectangle.numberOfBoxesInAColumn
             width: parent.width

             property int outerIndex: index

             Rectangle {
                id: individualRectangle
                color: Qt.rgba(1 / (outerIndex + 1), 0, 1 / (index + 1), 1)

                x: parentRectangle.width / parentRectangle.numberOfBoxesInARow * index
                y: outerIndex * parentRectangle.height / parentRectangle.numberOfBoxesInAColumn

                width: parentRectangle.width / parentRectangle.numberOfBoxesInARow
                height: parent.height / parentRectangle.numberOfBoxesInAColumn

                Component.onCompleted: {
                    console.log("Rectangle at " + outerIndex + "|" + index + " created, width / height: " + width.toFixed(2) + "| " + height.toFixed(2))
                }

                MouseArea {
                   anchors.fill: parent
                   onClicked: {
                      highlightAnimation.running = true
                   }
                }

                Rectangle {

                   id: highlightCircle

                   visible: highlightAnimation.running

                   color: 'white'

                   anchors.horizontalCenter: parent.horizontalCenter
                   anchors.verticalCenter: parent.verticalCenter
                   property real size: 0
                   width: size
                   height: size
                   radius: size/2
                }

                PropertyAnimation {
                   id: highlightAnimation
                   target: highlightCircle
                   property: 'size'
                   from: 200
                   to: 0
                   duration: 500
                }
             }
          }
       }
    }
}

Upvotes: 0

Views: 1067

Answers (1)

folibis
folibis

Reputation: 12874

Ok, to paint an item over another one you have at least 2 ways:

  • z (for siblings items only)
  • creating order (the last created is the highest)

I guess that the second way is preferable for you. So you just need to create the circle item after all others. For example:

Repeater {
    id: outerRepeater       
    Repeater {
        id: innerRepeater
        
        ...    
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    highlightCircle.item = individualRectangle;
                    highlightAnimation.running = true;
                }
            }
        }
    }
}

Rectangle {        
    id: highlightCircle
    property var item
    ...
    anchors.horizontalCenter: item ? item.horizontalCenter : undefined
    anchors.verticalCenter: item ? item.verticalCenter : undefined        
}

PropertyAnimation {
    id: highlightAnimation
    ...
}

Upvotes: 0

Related Questions