Clip QML Types with Context2D
-
The documentations talks about clipping images with a path drew with Contex2D:
http://doc.qt.io/qt-5/qml-qtquick-context2d.html#clip-method
is it possible to do the same but clipping any QML Type?
I mean, instead of the Image, I want to put any object (Text, Rectangle, ListView, etc....) but only the area inside the path should be visible. -
@Mark81 Hi! There is OpacityMask QML. Although it doesn't take a path but an image as source for the mask.
-
@Wieland Yes, I already use OpacityMask with (i.e.) a Rectangle with radius. It would be nice to use a generic path. Perhaps a workaround is to programmatically create an image with the desired path and use it as maskSource.
-
Out of curiosity, I implemented a
QQuickPaintedItem
-based PathMask type. The result looks like this:The code is:
pathmask.h#ifndef PATHMASK_H #define PATHMASK_H #include <QObject> #include <QQuickItem> #include <QQuickPaintedItem> #include <QPainter> #include <QPainterPath> class PathMask : public QQuickPaintedItem { Q_OBJECT public: explicit PathMask(QQuickItem *parent = Q_NULLPTR); ~PathMask(); virtual void paint(QPainter *painter); Q_INVOKABLE void beginPath(); Q_INVOKABLE void moveTo(qreal x, qreal y); Q_INVOKABLE void lineTo(qreal x, qreal y); Q_INVOKABLE void closePath(); private: QPainterPath *m_path{Q_NULLPTR}; }; #endif // PATHMASK_H
pathmask.cpp
#include "pathmask.h" #include <QPainterPath> #include <QtMath> PathMask::PathMask(QQuickItem *parent) : QQuickPaintedItem(parent) { } PathMask::~PathMask() { delete m_path; } void PathMask::paint(QPainter *painter) { if (m_path) { painter->setRenderHint(QPainter::Antialiasing); painter->setBrush( QBrush(QColor("black")) ); painter->drawPath( *m_path ); } } void PathMask::beginPath() { delete m_path; m_path = new QPainterPath; update(); } void PathMask::moveTo(qreal x, qreal y) { Q_ASSERT(m_path); m_path->moveTo(x,y); } void PathMask::lineTo(qreal x, qreal y) { Q_ASSERT(m_path); m_path->lineTo(x, y); } void PathMask::closePath() { Q_ASSERT(m_path); m_path->closeSubpath(); update(); }
main.qml
import QtQuick 2.5 import QtQuick.Controls 2.0 import QtQuick.Controls.Material 2.0 import QtGraphicalEffects 1.0 import io.qt.forum 1.0 ApplicationWindow { title: "PathMask Demo" visible: true width: 400 height: 400 color: "black" Image { id: src anchors.fill: parent visible: false source: "file:///home/patrick/Downloads/f22.jpg" } PathMask { id: mask anchors.fill: parent visible: false } Component.onCompleted: { mask.beginPath() mask.moveTo(360, 200); var Pi = 3.141592653589793238463; for (var i = 1; i < 5; ++i) { mask.lineTo(200 + 160 * Math.cos(0.8 * i * Pi), 200 + 160 * Math.sin(0.8 * i * Pi)); } mask.closePath(); } OpacityMask { anchors.fill: src source: src maskSource: mask } }