Is it possible in QML, maybe using shader effects with layers, to create an item that makes another item (with a higher z index) visible only when the two layers overlap? I've been messing aroud with OpacityMask and ThresholdMask but have been unable to figure it out. The effect I'm looking for in the context of the example below would be if the the black circle was only visible when the two red squares are under it:

current:

enter image description here

desired:

enter image description here

Some key points are that the bottom layer (red squares) must be moveable (OpacityMask doesn't seem to let you drag the maskSource) and the bottom layer needs to also be able to contain other elements within it that the black circle responds to. Any guidance towards the right things to learn in order to achieve this would be appreciated. Here is the QML for the red squares and black circle thing. The red squares are draggable as one element:

import QtQuick 2.9import QtQuick.Window 2.2import QtQuick.Layouts 1.12import QtGraphicalEffects 1.12Window {id: main_windowvisible: truewidth: 1500height: 1000title: qsTr("Hello World")Item {width: main_window.widthheight: main_window.heightLinearGradient {anchors.fill: parentstart: Qt.point(0, 0)end: Qt.point(main_window.width, 0)gradient: Gradient {GradientStop { position: 0.0; color: "#003cff" }GradientStop { position: 1.0; color: "#9afff9" }}}}Rectangle {id: sfgwidth: 175height: 75color: 'transparent'RowLayout {width: parent.widthheight: parent.heightspacing: 25Rectangle {Layout.preferredWidth: 75Layout.fillWidth: falseLayout.fillHeight: truecolor: 'red'}Rectangle {Layout.preferredWidth: 75Layout.fillWidth: falseLayout.fillHeight: truecolor: 'red'}}MouseArea {cursorShape: Qt.PointingHandCursoranchors.fill: parentdrag {target: sfg}}}Rectangle {id: maskcolor: 'black'x: 400y: 200width: 100height: 100visible: trueopacity: 1radius: 50}}
1

Best Answer


Like this?

import QtQuick 2.9import QtQuick.Window 2.2import QtQuick.Layouts 1.12import QtGraphicalEffects 1.12Window {id: main_windowvisible: truewidth: 1500height: 1000title: qsTr("Hello World")Item {width: main_window.widthheight: main_window.heightLinearGradient {anchors.fill: parentstart: Qt.point(0, 0)end: Qt.point(main_window.width, 0)gradient: Gradient {GradientStop { position: 0.0; color: "#003cff" }GradientStop { position: 1.0; color: "#9afff9" }}}}Rectangle {id: sgfBoxanchors.fill: parentcolor: "transparent"Rectangle {id: sfgwidth: 175height: 75color: 'transparent'RowLayout {width: parent.widthheight: parent.heightspacing: 25Rectangle {Layout.preferredWidth: 75Layout.fillWidth: falseLayout.fillHeight: truecolor: 'red'}Rectangle {Layout.preferredWidth: 75Layout.fillWidth: falseLayout.fillHeight: truecolor: 'red'}}MouseArea {cursorShape: Qt.PointingHandCursoranchors.fill: parentdrag {target: sfg}}}}Rectangle {id: maskanchors.fill: parentcolor: "transparent"Rectangle {color: 'black'x: 400y: 200width: 100height: 100opacity: 1radius: 50}layer.enabled: truelayer.effect: OpacityMask {maskSource: sgfBox}}}