QT QML 如何将 LinearGradient 添加到带边框的 Rectangle 中?

QT QML How to add LinearGradient to a Rectangle with a border?

我想要一个比 Rectangle 的默认垂直渐变更具体的渐变。我尝试添加 LinearGradient 以获得对角线效果,但它会覆盖边框。

考虑这个例子。 Top Rectangle 可以,垂直渐变和边框。底部 Rectangle 渐变覆盖边框和 radius。我尝试了 clipgradient: LinearGradient,但它们也没有用。

import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtGraphicalEffects 1.0

ApplicationWindow
{
    visible: true
    width: 640
    height: 480

    Column
    {
        spacing: 20
        width: parent.width
        Rectangle 
        {
            width: 200
            height: 200

            border.width: 4
            border.color: "#888"
            radius: 10

            // adds a vertical gradient to button
            gradient: Gradient
            {
                GradientStop 
                {
                    position: 0
                    color: "#eee"
                }
                GradientStop
                {
                    position: 1
                    color: "#ccc"
                }
            }
        }

        Rectangle 
        {
            width: 200
            height: 200

            border.width: 4
            border.color: "#888"
            radius: 10

            // try to add diagonal gradient, but overwrites button border
            // also can't do, gradient: LinearGradient  ?
            LinearGradient
            {
                anchors.fill: parent
                start: Qt.point(0,0)
                end: Qt.point(parent.width,parent.height)

                gradient: Gradient
                {
                    GradientStop 
                    {
                        position: 0
                        color: "#eee"
                    }
                    GradientStop
                    {
                        position: 1
                        color: "#ccc"
                    }
                }
            }
        }
    }
}

结果:

我明白为什么会出现这样的结果,但是如何将渐变裁剪为 Rectangleradius

QML 仅支持垂直渐变。您可以通过翻转项目的宽度和高度并旋转它来模拟水平渐变。

对于不适用的对角线,因为矩形也会旋转。

至于使用裁剪的计划,那也行不通,因为 QML 屏幕图形仅裁剪到项目的矩形,而不是其实际可见像素。

您可以采用两种方法:

1 - 尝试通过 Canvas 元素实现预期结果。

2 - 使用一个 ShaderEffect 传递一个带有渐变和圆角矩形的 ShaderEffectSource 纹理,然后在实际着色器中使用来自第一个源(渐变)的 rgb 和第二个(圆角矩形)的 alpha 要手动剪辑。

3 - 如果你打算使用 ShaderEffect 你可以轻松地跳过使用渐变作为源,并查看如何在 GLSL 中以任意角度实现渐变,并且只使用圆角alpha 的矩形源,即使 "rounded" 部分也可以在着色器中实现。

clip 总是在正在裁剪的 Item 的边界矩形处裁剪,并且不关心 alpha 值。

但是 LinearGradient 有另一个工具可以实现您想要的:
- source-property.

看这个例子:

import QtQuick 2.0
import QtQuick.Window 2.0
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtGraphicalEffects 1.0
Window {
    width: 1024
    height: 800
    visible: true

    Rectangle {
        id: rect1
        width: 100
        height: 100
        radius: 20
    }

    LinearGradient {
        anchors.fill: rect1
        source: rect1          <-- Here is where you specify its shape. 
        start: Qt.point(0, 0)
        end: Qt.point(300, 300)
        gradient: Gradient {
            GradientStop { position: 0.0; color: "white" }
            GradientStop { position: 1.0; color: "black" }
        }
    }
}