Gradient ignores parent rounded shape - qt

I am trying to create a circle with a gradient color inside. The rectangle with radius below works fine, but as soon as I added the RadialGradient it goes back to square shape. I tried adding an opacity mask but it didn't work. What's wrong with this?
import QtQuick 2.0
import QtGraphicalEffects 1.0
Rectangle {
id: light
property string type: ""
property bool connected: false
property bool flagSet: false
width: 50
height: width
radius: width / 2
RadialGradient {
anchors.fill: parent
gradient: Gradient {
GradientStop { position: 0.0; color: "green" }
GradientStop { position: 0.5; color: "black" }
}
}
OpacityMask {
anchors.fill: parent
source: light
maskSource: Rectangle {
height: light.height
width: light.width
radius: light.radius
}
}
}

This should do what you want:
Rectangle {
id: border
width: light.width + 2
height: width
radius: width / 2
color: "red"
RadialGradient {
id: light
anchors.centerIn: parent
width: 50
height: width
gradient: Gradient {
GradientStop { position: 0.0; color: "green" }
GradientStop { position: 0.5; color: "black" }
}
layer.enabled: true
layer.effect: OpacityMask {
id: mask
maskSource: Rectangle {
height: light.height
width: light.width
radius: width / 2
}
}
}
}

Related

QT QML what is the best approach for static layout

I need a complete static layout with fixed positions and sizes like this.
Do I need a grid or column layout with relative positioning or can I work without any layout (only with x and y positioning and fixed sizes)?
You could use positioners with Rectangles that have the static size set to them like this.
Column {
Rectangle { width: 100; height: 10; color: "#4472c4" }
Row {
Rectangle { width: 10; height: 60; color: "#8497b0" }
Rectangle { width: 80; height: 60; color: "#a6a6a6" }
Rectangle { width: 10; height: 60; color: "#333f50" }
}
Rectangle { width: 100; height: 10; color: "#d6dce5" }
}
You could also use x and y positioning without positioners.
Rectangle { width: 100; height: 10; color: "#4472c4" }
Rectangle { y: 10; width: 10; height: 60; color: "#8497b0" }
Rectangle { x: 10; y: 10; width: 80; height: 60; color: "#a6a6a6" }
Rectangle { x: 90; y: 10; width: 10; height: 60; color: "#333f50" }
Rectangle { y: 70; width: 100; height: 10; color: "#d6dce5" }
Or anchors
Rectangle { id: topRect; width: 100; height: 10; color: "#4472c4" }
Rectangle {
id: leftRect
anchors.top: topRect.bottom
anchors.left: parent.left
width: 10; height: 60; color: "#8497b0"
}
Rectangle {
id: centerRect
anchors.top: topRect.bottom
anchors.left: leftRect.right
x: 10; y: 10; width: 80; height: 60; color: "#a6a6a6"
}
Rectangle {
id: rightRect
anchors.top: topRect.bottom
anchors.left: centerRect.right
x: 90; y: 10; width: 10; height: 60; color: "#333f50"
}
Rectangle {
id: bottomRect
anchors.top: centerRect.bottom
y: 70; width: 100; height: 10; color: "#d6dce5"
}
Or you could use layouts, but I prefer positioners over layouts.
Here's a solution using Layouts. The advantage is, whilst I gave the dimensions 100x80 container, the outer Rectangles needed minimal 10 pixel sizing information, whilst the inner most Rectangle didn't need any sizing, since, I made use of Layout.fillWidth: true and Layout.fillHeight: true as appropriate.
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
ColumnLayout {
anchors.centerIn: parent
width: 100
height: 80
spacing: 0
Rectangle {
id: r1
Layout.fillWidth: true
Layout.preferredHeight: 10
color: "blue"
}
RowLayout {
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 0
Rectangle {
id: r2
Layout.preferredWidth: 10
Layout.fillHeight: true
color: "navy"
}
Rectangle {
id: r5
Layout.fillWidth: true
Layout.fillHeight: true
color: "grey"
}
Rectangle {
id: r4
Layout.preferredWidth: 10
Layout.fillHeight: true
color: "darkblue"
}
}
Rectangle {
id: r3
Layout.fillWidth: true
Layout.preferredHeight: 10
color: "lightsteelblue"
}
}
Text {
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
text: `
R1: ${r1.width} x ${r1.height}
R2: ${r2.width} x ${r2.height}
R3: ${r3.width} x ${r3.height}
R4: ${r4.width} x ${r4.height}
R5: ${r5.width} x ${r5.height}
`
}
}
You can Try it Online!

QML topmargin works only half

I am trying to move rectangles in an enclosing rectangle using topmargin.
The outer rectangle has a height of 80, the inner rectangles too.
If i set the topmargin to 0, the rectangles are displayed completely.
If I set the topmargin to 80, I would have thought that the rectangles would be moved completely. However, they are still displayed halfway.
only when I set the topMargin to double, i.e. 160, are the rectangles completely shifted?
Footer.qml
Rectangle { id: footer; color: "lightgrey"
property string p_buttonColor: "grey"
property int p_buttonHeight: 80
property int p_buttonWidth: 80
height: 80
width: 80
Layout.preferredHeight: height
Layout.preferredWidth: width
RowLayout{ anchors.centerIn: parent
FooterButton{ p_identity: "FB1"; height: p_buttonHeight; width: p_buttonWidth; color: p_buttonColor }
FooterButton{ p_identity: "FB2"; height: p_buttonHeight; width: p_buttonWidth; color: p_buttonColor }
FooterButton{ p_identity: "FB3"; height: p_buttonHeight; width: p_buttonWidth; color: p_buttonColor }
FooterButton{ p_identity: "FB4"; height: p_buttonHeight; width: p_buttonWidth; color: p_buttonColor }
FooterButton{ p_identity: "FB5"; height: p_buttonHeight; width: p_buttonWidth; color: p_buttonColor }
}
}
FooterButton.qml
Rectangle {
id: button
height: 80
property string p_identity
property string p_icon
property string p_source
Layout.preferredHeight: height
Layout.preferredWidth: width
radius: 10
Layout.topMargin: 80
Image { anchors.centerIn: parent; sourceSize.height: button.height * 0.7; source: p_source }
}

Get ProgressBar to fill Rectangle qml

I have a rectangle where I want to have a border around the Rectangle and the ProgressBar fit inside this rectangle while still being able to see the border.
Using qmlonline tool below I am able to create the Rectangle with ProgressBar, but the ProgressBar covers the whole Rectangle
import QtQuick 2.7
import QtQuick.Controls 2.3
Item {
width: 500
height: 250
Rectangle {
color: "black"
anchors.fill: parent
Rectangle {
id: rect1
width: 250
height: 50
border.width: 1
border.color: "white"
color: "transparent"
ProgressBar {
id: pBar
value: 0.5
background: Rectangle {
width: rect1.width
height: rect1.height
color: "gray"
}
contentItem: Item {
Rectangle {
width: pBar.visualPosition * rect1.width
height: rect1.height
color: "green"
}
}
}
}
}
}
I've tried modifying the background: and contentItem: components to get this to happen, but it doesn't work quite right.
Below is my attempt
import QtQuick 2.7
import QtQuick.Controls 2.3
Item {
width: 500
height: 250
Rectangle {
color: "black"
anchors.fill: parent
Rectangle {
id: rect1
width: 250
height: 50
border.width: 1
border.color: "white"
color: "transparent"
ProgressBar {
id: pBar
value: 1
background: Rectangle {
width: rect1.width
height: rect1.height * 0.925
anchors.verticalCenter: parent.verticalCenter
color: "gray"
}
contentItem: Item {
implicitWidth: rect1.width
implicitHeight: rect1.height
Rectangle {
width: pBar.visualPosition * rect1.width
height: rect1.height * 0.925
anchors.verticalCenter: parent.verticalCenter
color: "green"
}
}
}
}
}
}
When the progress is at 100% you can see that on the left and right side you cannot see rect1's border, but you can see it on the top and bottom.
use anchor instead of "width and height"
import QtQuick 2.7
import QtQuick.Controls 2.3
Item {
width: 500
height: 250
Rectangle {
color: "black"
anchors.fill: parent
Rectangle {
id: rect1
width: 250
height: 50
border.width: 1
border.color: "white"
color: "transparent"
ProgressBar {
id: pBar
value: 0.9
anchors.fill: parent
anchors.margins:1
background: Rectangle {
anchors.fill:parent
color: "gray"
}
contentItem: Item {
Rectangle {
width: pBar.visualPosition * parent.width
height: parent.height
color: "green"
}
}
}
}
}
}

How to make a particular area of qml view transparent

There is a qml file like this:
Item {
width: 800
height: 600
Image {
id: background
width: 800
height: 600
source: "qrc:/resorces/background.png"
}
Rectangle {
id: transframe
x: 500
y: 200
width: 200
height: 100
}
}
How to make the area of transframe transparent, then I can see the graphic under background.
The OpacityMask is what you are looking for.
Example:
Rectangle {
width: 800; height: 600
color: 'red'
Image {
id: background
width: 800; height: 600
source: "qrc:/resorces/background.png"
visible: false
}
Item {
id: transframe
width: 800; height: 600
visible: false
Rectangle {
x: 500; y: 200; width: 200; height: 100
}
}
OpacityMask { // don't forget to import QtGraphicalEffects
anchors.fill: background
source: background
maskSource: transframe
invert: true
}
}
Item {
width: 800
height: 600
Image {
id: background
width: 800
height: 600
source: "qrc:/resorces/background.png"
}
Rectangle {
id: transframe
x: 500
y: 200
width: 200
height: 100
color:"transparent"
}
}

Flick a column positioner

How do we make a Positioner for example a Column flickable.
For example :
import QtQuick 2.0
Item {
width: 200
height: 200
Column {
spacing: 2
Rectangle { color: "red"; width: 50; height: 50 }
Rectangle { color: "green"; width: 20; height: 50 }
Rectangle { color: "blue"; width: 50; height: 20 }
}
}
You need to at least set the following properties of the Flickable:
width and height (and/or anchors)
contentWidth and contentHeight
The following code should do the trick:
import QtQuick 2.0
Item {
width: 200
height: 200
Flickable {
//anchors.fill: parent
width: 100
height: 50
contentWidth: col.width // you can use whatever you want, this is just an example
contentHeight: col.height // same here
Column {
id: col
spacing: 2
Rectangle { color: "red"; width: 50; height: 50 }
Rectangle { color: "green"; width: 20; height: 50 }
Rectangle { color: "blue"; width: 50; height: 20 }
}
}
}

Resources