Reputation: 2613
I would like to have a more specific gradient than the default vertical one for a Rectangle
. I try adding a LinearGradient
for a diagonal effect, but it overwrites the border.
Consider this example. Top Rectangle
ok with vertical gradient and border. Bottom Rectangle
gradient overwrites border and radius
. I tried clip
and gradient: LinearGradient
but they didn't work either.
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"
}
}
}
}
}
}
Results in this:
I can see why this might have this result, but how to clip the gradient to a Rectangle
with a radius
?
Upvotes: 4
Views: 7592
Reputation: 13691
clip
always clips at the bounding rectangle of the Item
that is clipping, and does not care for alpha
-values.
However the LinearGradient
has another tool, to achive what you want:
- the source
-property.
See this example:
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" }
}
}
}
Upvotes: 5
Reputation: 49279
QML only supports vertical gradients. You can fake horizontal gradients by flipping the item's width and height and rotating it.
For a diagonal that won't work, as the rectangle would also be rotated.
As for the plan to use clipping, that won't work either, because the QML screnegraph only clips to the item's rectangle, not its actual visible pixels.
There are two approaches you ca take:
1 - try to accomplish the desired result via the Canvas
element.
2 - use a ShaderEffect
to which you pass a ShaderEffectSource
texture with the gradient and a rounded rectangle, then in the actual shader use the rgb from the first source (the gradient) and the alpha from the second (the rounded rectangle) to manually clip.
3 - if you are going to be using ShaderEffect
you can easily skip using a gradient as a source, and look up how to implement a gradient at an arbitrary angle in GLSL, and only use the rounded rectangle source for the alpha, even though the "rounded" part can just as well be implemented in the shader.
Upvotes: 0