I would like to know how to use, as progress bar, an image. Currently I use this code: `
ProgressBar {
id: pb
value: 0
minimumValue: 0
maximumValue: 100
style: ProgressBarStyle{
progress: Image {
source: "../icons/progress_full.png"
}
}
}
`
I would like that the "progression" reveals the image. Some suggestions?
What I got currently it's a distorced image that streatches to fill the rectangle.
1° Edit: I tried to follow Stephen Quan explanation doing this: I guess I lack some points on my code =(
import QtQuick 2.3
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import "."
Rectangle {
id: rectangle1
x: 0
y: 0
width: 600
height: 130
color: "#ffd1f9"
// -----------------
// PROPRIETA'
// -----------------
// Proprietà pubbliche
property int val: 50
property alias version: textVersion.text
property alias textColor: textVersion.color
// Proprietà private
QtObject {
id: d
property int firstColumn: 0
property int lastColumn: 260
}
// -----------------
// WIDGET
// -----------------
CFBrandConst {
id: brand
}
// Progressbar grafica
Item {
id: item1
x: 170
width: 271
height: 120
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
Image {
id: imgEmpty
cache: (Component.status == Component.Ready)
x: 0
y: -56
width: 260
height: 91
property real from: 0.0
property real to: 1.0
property real value: 0.0
anchors.top: parent.top
anchors.topMargin: 0
anchors.right: parent.right
anchors.rightMargin: 0
anchors.left: parent.left
anchors.leftMargin: 0
fillMode: Image.TileHorizontally
source: "../icons/progress_empty.png"
Image {
id: imgFull
cache: (Component.status == Component.Ready)
width: (to - value) / (to - from) * parent.width//260
anchors.top: parent.top
anchors.topMargin: 0
anchors.bottom: parent.bottom
anchors.bottomMargin: 0
anchors.left: parent.left
anchors.leftMargin: 0
source: "../icons/progress_full.png"
//sourceSize: Qt.size(width, height)
fillMode: Image.PreserveAspectFit
onSourceChanged: {
onValChanged();
}
}
}
Text {
id: textVersion
text: qsTr("version")
color: brand.fontColor
font.family: brand.fontFamily
font.pointSize: brand.fontPointSizeNormal
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
anchors.top: imgEmpty.bottom
anchors.topMargin: 0
anchors.bottom: parent.bottom
anchors.bottomMargin: 0
anchors.right: parent.right
anchors.rightMargin: 0
anchors.left: parent.left
anchors.leftMargin: 0
}
}
onValChanged: {
//SOME TENTATIVES HERE
val = Math.max(0, Math.min(100, val));
//imgFull.width = (100-val)/(100)*(d.lastColumn - d.firstColumn);
//imgFull.width = d.firstColumn (d.lastColumn d.firstColumn) * val / 100;
//pb.setValue(val);
imgEmpty.value= val;
}
}
CodePudding user response:
You should use Image
fillMode
property to avoid distortion. The basis comes from the following styling example.
import QtQuick
import QtQuick.Controls
Window {
id: root
color: "white"
width: 640
height: 480
visible: true
ProgressBar {
id: control
anchors.centerIn: parent
value: 0.5
padding: 2
background: Rectangle {
implicitWidth: 200
implicitHeight: 40
color: "#e6e6e6"
radius: 3
}
contentItem: Item {
id: content
implicitWidth: 200
implicitHeight: 40
Item {
width: control.visualPosition * parent.width
height: parent.height
clip: true
Image {
width: content.width
height: parent.height
fillMode: Image.PreserveAspectCrop
source: "https://picsum.photos/300/200"
}
}
}
}
Timer {
running: true
repeat: true
interval: 500
onTriggered: control.value = (control.value 0.02) % 1.0
}
}
CodePudding user response:
I noticed the ProgressBar
definition you're using appears to be from QtQuick 1? You will find support for QtQuick 1 to be waning. I base the following on the QtQuick 2 implementation of the ProgressBar
.
To cater for your requirements, I decided to reconstruct a ProgressBar
by using Rectangle
and Image
in a creative manner.
First, let's look at the Image
and how you're going to fit it into a Rectangle
progress bar. I gave it some thought and, most likely your source image is square? If that's the case, consider the following code:
Rectangle {
width: 200
height: 50
Image {
anchors.fill: parent
source: backgroundImage
sourceSize: Qt.size(height, height)
fillMode: Image.Tile
}
}
In the above, we have the following assumptions:
- The source backgroundImage is square, NxN pixels
- The progress bar is rectangle, e.g. 200x50
- We want to tile the background image in 50x50 tiles
To do that, we make use of sourceSize: Qt.size(50,50)
which will downsample your source image to fir the progressbar based on it's height. The fillMode: Image.Tile
which will cause the background image to be tiled neatly.
Here's a complete working example of the above implemented as MyProgressBar
with an animation showing the progress moving from 0.0 to 1.0.
import QtQuick
import QtQuick.Controls
Page {
background: Rectangle { color: "#848895" }
MyProgressBar {
id: pb
anchors.centerIn: parent
width: 300
height: 50
from: 0.0
to: 1.0
backgroundImage: "https://www.arcgis.com/sharing/rest/content/items/185841a46dd1440d87e6fbf464af7849/data"
}
NumberAnimation {
target: pb
property: "value"
loops: Animation.Infinite
running: true
from: 0; to: 1.0
duration: 10000
}
}
// MyProgressBar.qml
import QtQuick
import QtQuick.Controls
Rectangle {
width: 200
height: 50
property real from: 0.0
property real to: 1.0
property real value: 0.0
property url backgroundImage
border.color: "grey"
Image {
anchors.fill: parent
source: backgroundImage
sourceSize: Qt.size(height, height)
fillMode: Image.Tile
}
Rectangle {
anchors.right: parent.right
width: (to - value) / (to - from) * parent.width
height: parent.height
color: "steelblue"
border.color: "grey"
}
}
You can Try it Online!