How to use QSGClipNode with a custom geometry?
This is a sample:

- 5,013
- 7
- 44
- 59
-
What exactly the problem with using `setGeometry(QSGGeometry *geometry)`? – Velkan Mar 06 '17 at 08:57
-
I don't know how to use `QSGClipNode` and official documentation is poor. So this question will be a reference for anybody whom wants to know how to do clipping in the scenegraph within QQuickItem in a CORRECT WAY. – S.M.Mousavi Mar 06 '17 at 09:29
-
It's your question that is poor for StackOverflow. What have you tried? Any code to reproduce the problem? What was the error or the desired effect? Here is an example with `QSGGeometryNode`: http://doc.qt.io/qt-5/qtquick-scenegraph-customgeometry-example.html – Velkan Mar 06 '17 at 10:03
-
Do you tried to use `QSGClipNode`?! It is different from `QSGGeometryNode`. My question is very simple and clear... "how to use QSGClipNode?" Have you any sample code which uses `QSGClipNode`? – S.M.Mousavi Mar 06 '17 at 10:12
1 Answers
QSGClipNode
The QSGClipNode
uses its geometry to clip rendering of its children nodes.
So to use it, you first have to create the geometry (set of vertices/triangles) representing your mask, and set it with the setGeometry
method. Resources are scarce yes, here is a few examples using QSGGeometry
, that you need to draw your "heart" shape:
- an example creating a custom geometry using QSG : QQuickPolygon
- an old presentation I made (a bit surprised it shows up in google first results)
- and an example from Qt documentation
Then use the appendChildNode
method to add the children that you want to clip in your QSGClipNode. In your case, QSGImageNode
is probably the way to go, to show your image clipped.
Other solution: OpacityMask
Another solution, available without digging into c++ scene graph classes, is to use an OpacityMask
from QtQuick.GraphicalEffect
. It also applies to a QtQuickItem you would have created in C++.
The example in Qt documentation is easy to use, just don't forget to set the visible
property of both the Mask and the Source to false
, the OpacityMask
element itself will display the source cropped/masked.
Here is a way to clip "children" with it (NB: untested at that time):
clipperitem.qml
import QtQuick 2.5
import QtGraphicalEffects 1.0
Item {
width: 300
height: 300
// Item-based children will be mapped to this property
default property alias clippedContent: clippedItem.children
// Optional mask property to set it from outside
property alias mask: opacityMask.mask
Item {
id: clippedItem
anchors.fill: parent
visible: false
}
Item {
id: defaultMask
// Your default mask
visible: false
}
OpacityMask {
id: opacityMask
anchors.fill: clippedItem
source: clippedItem
mask: defaultMask
}
}
main.qml
ClipperItem {
// Content here will be clipped. Non item-based elements will have
// to be explicitly assigned to `ressources` property (i.e. Timer, etc.)
Rectangle {
//...
}
Image {
//...
}
}

- 2,731
- 18
- 32
-
OK, I test it and it clips its child node. Is there any way to clip child QQuickItems? Assume in QML `MyClipItem { width: 45; height: 45; Rectangle { id: rec; width: 50; height: 50; color: "red"; radius: 20 } }` Is it possible to clip `rec` using `MyClipItem`? – S.M.Mousavi Mar 09 '17 at 09:01
-
Good, I would assume it works directly as in your case, your Rectangle is reparented to `MyClipItem`. Have you tried it alredy ? – Adrien Leravat Mar 09 '17 at 09:38
-
I tested it and it works perfect for `QSGNodes` as children but in earlier comment, my Rectangle named `rec` is not clipped. In other words QSGClipNode not clips QQuickItems children such as `rec`. – S.M.Mousavi Mar 09 '17 at 14:11
-
Please try with MyClipItem { clip: true; /*...*/ }, this should do the trick ! – Adrien Leravat Mar 09 '17 at 15:33
-
Ok right, that's actually normal. I edited my answer to include the OpacityMask, which might be helping to you, even though in that case you don't need a `GSGClipNode` anymore. It's however completely possible to use a QSGGeometry in a QQuickItem as the mask – Adrien Leravat Mar 10 '17 at 19:54
-
OK thanks, first section of your answer is the actual answer for my question. Also your alternate solution for clipping using GLSL works perfectly. After testing your first approach I found out that It doesn't clips QQuickItem children. So I'm interested to find a way to clipping children QQuickItems as normal rectangular clipping through C++ but with a custom shape. So I can use it in QML as an Item named: `ClipperItem` – S.M.Mousavi Mar 11 '17 at 06:08
-
I included an example of how this could be achieved using `OpacityMask` – Adrien Leravat Mar 11 '17 at 09:25
-