How to Draw a circular progress Bar using QML in QT6 - qt

Conical gradient is not there in Qt6 and hence i want a circular progress bar just like the code. But i am unable to use Conical Gradient because import QtGraphicalEffects 1.15 is scrapped in Qt6
This is my code is there another alternative for Conical Gradient
Main .qml
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import QtQuick.Controls.Styles 1.4
import QtGraphicalEffects 1.0
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
Custom_Temp{
anchors.centerIn: parent
from_value: 0
to_value: 100
range_1: 35
range_2: 50
range_3: 80
unit: "°"
vlaue: 60
}
}
Custom_temp.qml
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import QtQuick.Controls.Styles 1.4
import QtGraphicalEffects 1.15
Item {
property int from_value
property int to_value
property int range_1
property int range_2
property int range_3
property alias vlaue: main_progress_bar.value
property string unit
ProgressBar{
anchors.centerIn: parent
id:main_progress_bar
from: from_value
to: to_value
property string actual_color: value >= range_2 ? "red": value >= range_1? "#ffe208" : "green"
background: Rectangle {
implicitWidth: 100
implicitHeight: 6
color: "transparent"
radius: 3
}
contentItem:
Rectangle{
color: "transparent"
implicitWidth: 100
implicitHeight: implicitWidth
Rectangle
{
id: outerRing
z: 10
anchors.fill: parent
radius: Math.max(width, height) / 2
color: "transparent"
border.color: "gray"
border.width: 16
}
Rectangle
{
id: innerRing
z: 10
anchors.fill: parent
anchors.margins: (outerRing.border.width - border.width) / 2
radius: outerRing.radius
color: "transparent"
border.color: "darkgray"
border.width: 8
ConicalGradient
{
source: innerRing
anchors.fill: parent
gradient: Gradient
{
GradientStop { position: 0.00; color: main_progress_bar.actual_color }
GradientStop { position: main_progress_bar.value/100; color: main_progress_bar.actual_color }
GradientStop { position: (main_progress_bar.value/100) + 0.01; color: "transparent" }
GradientStop { position: 1.00; color: "transparent" }
}
}
}
Label
{
id: progressLabel
anchors.centerIn: parent
color: main_progress_bar.value >= range_2? "red": main_progress_bar.value >= range_1? "#ffe208" : "green"
text: (main_progress_bar.value.toFixed(1)) + "°"
font.pixelSize: 20
}
}
}
}
is there an alternative for conicalGradient in Qt6?

There is a ConicalGradient in Qt6, but you have to use:
import Qt5Compat.GraphicalEffects

Related

Mask from pictures, crop image behind cursor

I have a basic background from a blue image with a transparent background (PNG), how can I make a different background from the image after the arrow?
I tried the option using a mask, but it cuts the picture either in width or in height, this does not work
blue background:
it should be:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Window 2.15
import QtQuick.Controls.Styles 1.4
import QtQuick.Extras 1.4
import QtQuick.Extras.Private 1.0
import QtGraphicalEffects 1.0
Window {
width: 1280
height: 480
visible: true
title: qsTr("Hello World")
color: "#000"
CircularGauge {
id:gauge
property bool accelerating
width: 377
height: 377
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 101
maximumValue:8
value: accelerating ? maximumValue : 0
Component.onCompleted: forceActiveFocus()
Behavior on value { NumberAnimation { duration: 1500 }}
Keys.onSpacePressed: accelerating = true
Keys.onReleased: {
if (event.key === Qt.Key_Space) {
accelerating = false;
event.accepted = true;
}
}
style: CircularGaugeStyle {
labelStepSize: 1
labelInset: outerRadius / 6
minimumValueAngle: -110
maximumValueAngle: 110
background: Rectangle {
id: rectangle
implicitHeight: gauge.height
implicitWidth: gauge.width
color:"Transparent"
anchors.centerIn: parent
radius: 360
Image {
width: 417
height: 287
anchors.top: parent.top
source: "Blue_bg.png"
anchors.topMargin: -23
anchors.horizontalCenter: parent.horizontalCenter
asynchronous: true
sourceSize {
}
}
}
foreground: Item {
Text {
id: speedLabel
anchors.centerIn: parent
anchors.verticalCenterOffset: -20
text: "126"
font.pixelSize:76
color: "white"
antialiasing: true
}
}
tickmarkLabel: Text {
font.italic: true
font.bold: true
text: styleData.value
font.pixelSize: 30
color: styleData.value <= gauge.value ? "white" : "#ffffff"
antialiasing: true
}
}
}
}
How can I achieve this effect?
You can use a Canvas to draw an arc (see Draw an arc/circle sector in QML?). If you combine this with an OpacityMask (see QML Circular Gauge) you can mask the blue "background" (it's more like a foreground in the given example) to make that cool speedometer :-)
import QtQuick 2.12
import QtQuick.Window 2.12
import QtGraphicalEffects 1.0
Window {
width: 640
height: 480
visible: true
Image {
id: img
source: "blue.png"
visible: false
}
Canvas {
id: mask
anchors.fill: img
property double angle: 45
onPaint: {
var ctx = getContext("2d");
var centerX = width / 2;
var centerY = height / 2;
ctx.beginPath();
ctx.fillStyle = "black";
ctx.moveTo(centerX, centerY);
ctx.arc(centerX, centerY, width / 4, (Math.PI) * (1 + angle / 180), 0, false);
ctx.lineTo(centerX, centerY);
ctx.fill();
}
}
OpacityMask {
anchors.fill: img
source: img
maskSource: mask
}
}

I faced a conflict in using DropShadow and Ripple

I wrote a Ripple item in a Rectangle Item and enabled clip property of the Rectangle to prevent the Ripple drawing get out of that Rectangle.
without DropShadow:
Everything works fine until I add a DropShadow to that Rectangle. Although it is outside the Rectangle item, but it neutralizes the clip effect in left and right side of the Rectangle.
with DropShadow:
Here is my code:
import QtQuick 2.12
import QtQuick.Layouts 1.12
import QtGraphicalEffects 1.12
import QtQuick.Controls.Material.impl 2.12
Item{
width: 400
height: 100
DropShadow {
anchors.fill: itemRect
horizontalOffset: 0
verticalOffset: 0
radius: 12.0
samples: 17
color: "#50000000"
source: itemRect
}
Rectangle{
id:itemRect
anchors.fill: parent;
anchors.margins: 8;
border.width: 1
radius: 5;
clip: true;
MouseArea{
id: button
anchors.fill: parent
onPressed: {
ripple.x=mouseX-(ripple.width/2);
ripple.y=mouseY-(ripple.height/2);
}
Ripple {
id: ripple
clipRadius: 2
x:40
width: itemRect.width*2
height: itemRect.height*2
pressed: button.pressed
active: false
color: "#10000000"
// layer.enabled: true
// layer.effect: OpacityMask {
// maskSource: Rectangle
// {
// width: ripple.height
// height: ripple.height
// radius: ripple.height
// }
// }
}
}
}
}
I tested OpacityMask for layer.effect of Ripple Item. But it didn't have any effects.
Finaly i wrote my own Ripple.
It can be used anywhere without any issues.
https://github.com/mmjvox/Another-Ripple
here is my code:
import QtQuick 2.12
import QtQuick.Layouts 1.12
import QtGraphicalEffects 1.12
import AnotherRipple 1.0
Item{
width: 400
height: 100
DropShadow {
anchors.fill: itemRect
horizontalOffset: 0
verticalOffset: 0
radius: 12.0
samples: 17
color: "#50000000"
source: itemRect
}
Rectangle{
id:itemRect
anchors.fill: parent;
anchors.margins: 8;
border.width: 1
radius: 5;
clip: true;
SimpleRipple{
id: ripple
anchors.fill: parent;
color: "#50ffa070"
}
MouseArea{
id: button
anchors.fill: parent
onClicked: {
// In this example MouseArea accepts pressed event to provide clicked(released) event.
// Ripple can't sense pressed event, so I called pressed method of Ripple.
ripple.pressed(mouse.x,mouse.y);
// Some Other Operations
}
}
}
}

PieMenuStyle in qml error ReferenceError: __control is not defined, how to fix this error

I'm using qt 5.12, tried running an example code of PieMenuStyle and got these error.
file:///home/aishu/Qt5.12.10/5.12.10/gcc_64/qml/QtQuick/Controls/Private/Style.qml:52: **ReferenceError: __control is not defined
leads to line
readonly property Item control: __control
file:///home/aishu/Qt5.12.10/5.12.10/gcc_64/qml/QtQuick/Controls/Styles/Base/PieMenuStyle.qml:147: **TypeError: Cannot read property 'width' of null**
leads to line
readonly property real radius: Math.min(control.width, control.height) * 0.5
file:///home/aishu/Qt5.12.10/5.12.10/gcc_64/qml/QtQuick/Controls/Styles/Base/PieMenuStyle.qml:113: **ReferenceError: __control is not defined**
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5
import QtQuick.Controls.Styles 1.4
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
PieMenuStyle {
shadowRadius: 0
menuItem: Item {
id: item
rotation: -90 + sectionCenterAngle(styleData.index)
Rectangle {
width: parent.height * 0.2
height: width
color: "darkorange"
radius: width / 2
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
Text {
id: textItem
text: control.menuItems[styleData.index].text
anchors.centerIn: parent
color: control.currentIndex === styleData.index ? "red" : "white"
rotation: -item.rotation
}
}
}
}
}
PieMenuStyle is used to modify the style of a PieMenu but your code does not see any, so the solution is to add it and place the PieMenuStyle as the style of the PieMenu:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 1.4
import QtQuick.Extras 1.4
import QtQuick.Controls.Styles 1.4
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
PieMenu {
id: pieMenu
anchors.centerIn: parent
MenuItem {
text: "Action 1"
onTriggered: print("Action 1")
}
MenuItem {
text: "Action 2"
onTriggered: print("Action 2")
}
MenuItem {
text: "Action 3"
onTriggered: print("Action 3")
}
style: PieMenuStyle {
shadowRadius: 0
menuItem: Item {
id: item
rotation: -90 + sectionCenterAngle(styleData.index)
Rectangle {
width: parent.height * 0.2
height: width
color: "darkorange"
radius: width / 2
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
Text {
id: textItem
text: control.menuItems[styleData.index].text
anchors.centerIn: parent
color: control.currentIndex === styleData.index ? "red" : "white"
rotation: -item.rotation
}
}
}
}
}
Component.onCompleted: pieMenu.popup(0, 0)
}

QML ProgressBar invalid property name "style"

I try to use QML ProgressBar.
Here is the documentation
https://doc.qt.io/qt-5/qml-qtquick-controls-styles-progressbarstyle.html#details
I try this code
import QtQuick 2.14
import QtQuick.Controls 2.15
import QtQuick.Window 2.14
import QtQuick.Controls.Styles 1.4
Window {
id: root
width: 300; height: 300
ProgressBar {
value: 0.5
style: ProgressBarStyle {
background: Rectangle {
radius: 2
color: "lightgray"
border.color: "gray"
border.width: 1
implicitWidth: 200
implicitHeight: 24
}
progress: Rectangle {
color: "lightsteelblue"
border.color: "steelblue"
}
}
}
}
But I have the error invalid property name "style". What i doing wrong?
You're mixing the styling from Qt Quick Controls 1 with Qt Quick Controls 2. To customise a ProgressBar in Qt Quick Controls 2, see this page:
import QtQuick 2.12
import QtQuick.Controls 2.12
ProgressBar {
id: control
value: 0.5
padding: 2
background: Rectangle {
implicitWidth: 200
implicitHeight: 6
color: "#e6e6e6"
radius: 3
}
contentItem: Item {
implicitWidth: 200
implicitHeight: 4
Rectangle {
width: control.visualPosition * parent.width
height: parent.height
radius: 2
color: "#17a81a"
}
}
}
import QtQuick.Controls 2.15
...
import QtQuick.Controls.Styles 1.4
You are using two different versions of QtQuick here, ie. you have imported ProgressBar from QtQuick.Controls 2.15 which does not have a style property (https://doc.qt.io/qt-5/qml-qtquick-controls2-progressbar.html).
More information about differences can be found here:
https://doc.qt.io/qt-5/qtquickcontrols2-differences.html

How to add animation to a component while destroying in QML

I am adding Animation to my project and most of the UI is dynamic. Currently, i am not able to add animation to the Component while destroying. Following is the test application code which describes the same:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
property bool removeClicked : true
Row{
anchors.bottom: parent.bottom
spacing:20
Button{
text:"Add"
onClicked: {
removeClicked = false
comp.createObject(myrow)
}
}
Button{
id:remBtn
text:"Remove"
onClicked: {
removeClicked = true
myrow.children[0].destroy() //Destroy the object
}
}
}
Row{
id:myrow
height:40
spacing:20
}
Component{
id:comp
Rectangle{
width:20
height:30
color: "red"
NumberAnimation on opacity{
id: destroyAnimation
from :removeClicked ? 1:0
to: removeClicked ? 0:1
duration: 1000
}
}
}
}
Any help will be Appreciated!!!
Shou should perform the animation before calling destroy on your dynamically created items. You could use a SequentialAnimation, combined with a ScriptAction to do so.
Here's a small example (the dynamic balls get destroyed when one clicks on them).
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
Window {
visible: true
width: 640
height: 480
Button{
text:"Add"
anchors.centerIn: parent
onClicked: {
comp.createObject(parent)
}
}
Component{
id:comp
Rectangle{
id: ball
height:30
width:height
radius: height/2
x: Math.random()*parent.width-width
y: Math.random()*parent.height-height
color: Qt.hsla(Math.random(), 0.5, 0.5, 1)
opacity: 0
Component.onCompleted: opacity = 1
Behavior on opacity{ NumberAnimation {}}
SequentialAnimation
{
id: destroyAnim
ScriptAction{script: ball.opacity = 0}
NumberAnimation{target: ball; property:"scale"; to: 5}
ScriptAction{script: ball.destroy()}
}
MouseArea
{
anchors.fill: parent
onClicked:destroyAnim.start()
}
}
}
}

Resources