I have a group of filters. When we click on one them, this object must change color and image color. Then we click again and it goes to the default settings.
This is how it should look like (first object is a turned on object, others is turned off):
This is a code of rowLayout that includes these objects:
RowLayout{
spacing: 32
Rectangle{
height: 64
width: 64
color: "#2E2E2E"
radius: 8
border.width: 0
border.color: "#C9A86B"
Image {
id: youTube
source: "qrc:/Images/youTube.svg"
anchors.centerIn: parent
}
ColorOverlay {
id: overlay
anchors.fill: youTube
source: youTube
color: "#FFFFFF"
}
MouseArea{
anchors.fill: parent
onPressed:{
parent.border.width = 1
overlay.color = "#C9A86B"
}
}
}
Rectangle{
height: 64
width: 64
color: "#2E2E2E"
radius: 8
Image {
id: img
source: "qrc:/Images/img.svg"
anchors.centerIn: parent
}
ColorOverlay {
id: overlay2
anchors.fill: img
source: img
color: "#FFFFFF"
}
MouseArea{
anchors.fill: parent
onPressed:{
parent.border.color = "#C9A86B"
overlay2.color = "#C9A86B"
}
}
}
Rectangle{
height: 64
width: 64
color: "#2E2E2E"
radius: 8
Image {
id: headphones
source: "qrc:/Images/headphones.svg"
anchors.centerIn: parent
}
ColorOverlay {
id: overlay3
anchors.fill: headphones
source: headphones
color: "#FFFFFF"
}
MouseArea{
anchors.fill: parent
onPressed:{
parent.border.color = "#C9A86B"
overlay3.color = "#C9A86B"
}
}
}
}
CodePudding user response:
Whilst ColorOverlay
can be used to recolor an image, I found that the way how it does it was rather brute-force. Alternatively, many components actually have a built-in way for recoloring an SVG
image via the icon property. For example:
Rectangle {
Layout.preferredWidth: 64
Layout.preferredHeight: 64
clip: true
Button {
anchors.centerIn: parent
background: Item { }
icon.source: "play-32.svg"
icon.width: 32
icon.height: 32
icon.color: checked ? "#c9a86b" : "white"
checkable: true
}
}
You see in the above, we control the size, and the color and we also implement a clickable component with just the Button
component. Since Button
is being used, your "switchable" requirement can be implemented by setting checkable
to true and watching the value of the checked
property.
The only thing we don't want is the default rendering of the Button
so the first thing is we remove the background and then, we have to clip the Button
(put it inside a Rectangle
or an Item
) to control the dimensions we want.
In the following example, I used slightly different SVG
assets than the one shown in your screenshot. To use SVG
as an icon, they are effectively monochrome since whatever color was specified within will be replaced when it is recolored. The original youtube.svg
had two polygons one for the outer polygon and one for the inner polygon in different colors. I had to edit this so that it was done as a single polygon with a donut play button hole.
I refactored the checkable SVG button as AppButton.qml
.
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
background: Rectangle { color: "black" }
ColumnLayout {
anchors.centerIn: parent
spacing: 32
RowLayout {
spacing: 32
AppButton {
id: btnPlay
icon.source: "youtube.svg"
icon.width: 48
icon.height: 40
checked: true
}
AppButton {
id: btnImage
icon.source: "image.svg"
}
AppButton {
id: btnSound
icon.source: "headset.svg"
}
}
Text {
Layout.alignment: Qt.AlignHCenter
text: btnPlay.checked "," btnImage.checked "," btnSound.checked
color: "#c9a86b"
}
}
}
// AppButton.qml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Rectangle {
Layout.preferredWidth: 64
Layout.preferredHeight: 64
color: "#2e2e2e"
border.color: btn.checked ? "#c9a86b" : "transparent"
radius: 8
property alias checked: btn.checked
property alias pressed: btn.pressed
property alias icon: btn.icon
Button {
id: btn
anchors.centerIn: parent
background: Item { }
icon.width: 48
icon.height: 48
icon.color: checked ? "#c9a86b" : "white"
checkable: true
}
}
// youtube.svg
<svg xmlns="http://www.w3.org/2000/svg" height="800" width="1200" viewBox="-35.20005 -41.33325 305.0671 247.9995">
<path d="M229.763 25.817c-2.699-10.162-10.65-18.165-20.747-20.881C190.716 0 117.333 0 117.333 0S43.951 0 25.651 4.936C15.554 7.652 7.602 15.655 4.904 25.817 0 44.237 0 82.667 0 82.667s0 38.43 4.904 56.85c2.698 10.162 10.65 18.164 20.747 20.881 18.3 4.935 91.682 4.935 91.682 4.935s73.383 0 91.683-4.935c10.097-2.717 18.048-10.72 20.747-20.88 4.904-18.422 4.904-56.851 4.904-56.851s0-38.43 -4.904 -56.85
L93.333 117.558 l0 -69.9 61.334 34.89 -61.334 34.893 z" fill="#282828"/>
</svg>
// image.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M2 5v22h28V5zm27 21H3v-5.474l4.401-3.5 1.198.567L14 13.106l5 4.531 3.506-3.123L29 20.39zm-5.997-12.422a.652.652 0 0 0-.926-.033L19 16.293l-4.554-4.131a.652.652 0 0 0-.857-.013L8.45 16.417l-.826-.391a.642.642 0 0 0-.72.117L3 19.248V6h26v13.082zM19 8a2 2 0 1 0 2 2 2.002 2.002 0 0 0-2-2zm0 3a1 1 0 1 1 1-1 1.001 1.001 0 0 1-1 1z"/><path fill="none" d="M0 0h32v32H0z"/></svg>
// headset.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M28.76 12.716l-1.207-.605a1.057 1.057 0 0 0-.263-.09C26.125 6.69 22.513 2.201 16 2.201 7.906 2.2 4.084 9.13 4.084 16H3v1h2.132c-.027-.33-.048-.663-.048-1a14.703 14.703 0 0 1 2.72-8.871A9.89 9.89 0 0 1 16 3.2c5.956 0 9.26 4.163 10.326 9.108a1.074 1.074 0 0 0-.325.762v5.86a1.07 1.07 0 0 0 .215.628 11.247 11.247 0 0 1-7.651 7.886A1.495 1.495 0 0 0 17.5 27h-2a1.5 1.5 0 0 0 0 3h2a1.5 1.5 0 0 0 1.5-1.5c0-.047-.01-.092-.014-.138a12.252 12.252 0 0 0 8.138-8.367 1.06 1.06 0 0 0 .429-.106l1.206-.605A2.23 2.23 0 0 0 30 17.276v-2.552a2.232 2.232 0 0 0-1.24-2.008zM17.5 29h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 0 1zM29 17.276a1.237 1.237 0 0 1-.688 1.114l-1.207.604-.103-.064v-5.86l.103-.064 1.208.604A1.238 1.238 0 0 1 29 14.724z"/><path fill="none" d="M0 0h32v32H0z"/></svg>
You can Try it Online!