自定义形状后剪辑自定义QML项目的子项

Jac*_*ieg 1 c++ qt qml qtquick2 qquickitem

我有一个QQuickItem创建的自定义,我想创建一个圆角的窗口。因此,我实施了QQuickPaintedItem并导出到QML。问题在于该项目的子项正在通过该项目的边界矩形扩展,该矩形是一个矩形,而不是我想要的圆角矩形。外观如下:

在此处输入图片说明

这是我的代码:

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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();
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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();
}
Run Code Online (Sandbox Code Playgroud)

我想要的是孩子Rectangle的拐角处被我的自定义形状(在这种情况下是圆角矩形)修剪的形状。

在此处输入图片说明

是否有可能实现这样的目标QML

Arp*_*ius 6

我不知道QQuickPaintedItem是否可能(它应该在您使用fill时使用,而不是仅在边框时使用),但是如果不创建自定义QSGNode(非常hacky),唯一的方法是使用opacitymask

Rectangle{
    id: mask
    width:100
    height: 100
    radius: 30
    color: "red"
    border.color: "black"
    border.width: 1
}

Item {
    anchors.fill: mask
    layer.enabled: true
    layer.effect: OpacityMask {
        maskSource: mask
    }
    Rectangle {
        anchors.fill: parent
        anchors.margins: 5
        color:"yellow"
    }
}
Run Code Online (Sandbox Code Playgroud)

这给你:

蒙版和剪切的矩形

但是使用它将是GPU的一项艰巨任务,因为必须先在缓冲区上绘制内部项和蒙版,然后在窗口上重新绘制,因此对于旧的移动设备或性能较弱的嵌入式设备而言,效果不是很好。

  • 为什么创建自定义QSGNode“非常hacky”? (2认同)