Home > OS >  How to make an object switchable?
How to make an object switchable?

Time:12-03

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):

enter image description here

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!

  • Related