I have a custom QQuickItem
which I created and I wanted to create a rounded cornered window. So I implemented a QQuickPaintedItem
and exported to QML
. The problem is that the item's children are expanding by the item's bounding rectangle, which is a rectangle and not a rounded rectangle like I want it. Here's how it looks:
Here is my code:
main.qml
import QtQuick 2.7
import QtQuick.Window 2.2
import mycustomlib 1.0
Window {
id: wnd
width: 300
height: 280
visible: true
flags: Qt.FramelessWindowHint
color: "transparent"
x: 250
y: 250
MyCustomWindow {
id: playerFrame
anchors.fill: parent
radius: 25
Rectangle {
color: "beige"
anchors.margins: 5
anchors.fill: parent
}
}
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QUrl>
#include "mycustomwindow.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterType<MyCustomWindow>("mycustomlib", 1, 0, "MyCustomWindow");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
mycustomwindow.h
#ifndef MYCUSTOMWINDOW_H
#define MYCUSTOMWINDOW_H
#include <QQuickPaintedItem>
class MyCustomWindow : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(int radius READ radius WRITE setRadius NOTIFY radiusChanged)
public:
MyCustomWindow(QQuickItem *parent = 0);
int radius() const;
void setRadius(int radius);
signals:
void radiusChanged();
protected:
virtual void paint(QPainter *pPainter) Q_DECL_OVERRIDE;
private:
int m_radius;
};
#endif // MYCUSTOMWINDOW_H
mycustomwindow.cpp
#include "mycustomwindow.h"
#include <QPainter>
MyCustomWindow::MyCustomWindow(QQuickItem *parent) :
QQuickPaintedItem(parent),
m_radius(0)
{
setAcceptedMouseButtons(Qt::AllButtons);
}
void MyCustomWindow::paint(QPainter *pPainter)
{
const QRect myRect(0, 0, width() - 1, height() - 1);
pPainter->fillRect(myRect, Qt::transparent);
pPainter->drawRoundedRect(myRect, m_radius, m_radius);
}
int MyCustomWindow::radius() const
{
return m_radius;
}
void MyCustomWindow::setRadius(int radius)
{
m_radius = radius;
emit radiusChanged();
}
What I would like is the child Rectangle
's cornered to be clipped by my custom shape(which in this case is a rounded rectangle. Something like this:
Is it possible to achieve something like this in QML
?
I don't know if it is possible with QQuickPaintedItem(it should as you use fill, rather then border only), but without creating custom QSGNode(very hacky), the only way is to use opacitymask:
Which gives you:
But using it will be GPU consuming task as the inner item and mask have to be drawn on buffer first and then redrawn on window, so not very good for old mobile or weak embedded devices.