Home > database >  QT QML how to create a reusable button component
QT QML how to create a reusable button component

Time:01-14

I have some simulated buttons in on rectangle. These buttons I need at different places in the app. Is it possible to make a kind of component out of it?

This is how it is currently

RowLayout {
    anchors.fill: parent

    Rectangle {
        id: button1
        height: _buttonsHeight * 0.6
        width: height
        radius: height / 2
        border.width: 1
        border.color: "black"

        Image {
            anchors.centerIn: parent
            source: "image://iconProvider/icons/128/button1.png"
            sourceSize.height: parent.height * 0.8
        }

        MouseArea {
            anchors.fill: parent
            onPressed: btnHome.border.width = 2
            onReleased: btnHome.border.width = 0
            onClicked: userInputDevice.buttonClicked("button1")
        }
    }

    Rectangle {
        id: button2
        height: _buttonsHeight * 0.6
        width: height
        radius: height / 2
        border.width: 1
        border.color: "black"

        Image {
            anchors.centerIn: parent
            source: "image://iconProvider/icons/128/button2.png"
            sourceSize.height: parent.height * 0.8
        }

        MouseArea {
            anchors.fill: parent
            onPressed: btnHome.border.width = 2
            onReleased: btnHome.border.width = 0
            onClicked: userInputDevice.buttonClicked("button2")
        }
    }
}

Something like this would be the goal

RowLayout {
    anchors.fill: parent
    Button {id = "button1", height = _buttonsHeight * 0.6, icon = "button1.png", command = "button1", parent = this}
    Button {id = "button2", height = _buttonsHeight * 0.6, icon = "button2.png", command = "button2", parent = this}
}

Is something like this feasible ?

Thanks and best regards

Arne

CodePudding user response:

You should read the documentation about QML defining types.

Don't use the assignment operator, but the colon to create bindings. No need to set any parent.

For the nested Image.source property you should create an alias property in the root of your component like so property alias imageSource: <imageID>.source to be able to set it from the outside.

import QtQuick
import QtQuick.Layouts

Window {
    id: root
    width: 320
    height: 240
    visible: true

    property int btnHeight: 80

    component CustomButton : Rectangle {
        property alias icon: image.source
        signal pressed
        signal released
        signal clicked

        id: buttonRoot
        height: 20
        width: height
        radius: height / 2
        border.width: 1
        border.color: "black"

        Image {
            id: image
            anchors.centerIn: parent
            source: "https://upload.wikimedia.org/wikipedia/commons/7/72/Variable_Resistor.svg"
            fillMode: Image.PreserveAspectFit
            width: buttonRoot.height / Math.sqrt(2)
            height: image.width
        }

        MouseArea {
            anchors.fill: parent
            onPressed: buttonRoot.pressed()
            onReleased: buttonRoot.released()
            onClicked: buttonRoot.clicked()
        }
    }

    RowLayout {
        anchors.centerIn: parent
        spacing: 20

        CustomButton {
            id: button1
            height: root.btnHeight
            onClicked: console.log("Button 1 clicked")
        }
        CustomButton {
            id: button2
            height: root.btnHeight
            icon: "https://upload.wikimedia.org/wikipedia/commons/f/fd/Crystal_Clear_app_download_manager.svg"
            onClicked: console.log("Button 2 clicked")
        }
    }
}

CodePudding user response:

You can create a new qml file let's name it MyButton.qml

MyButton is a custom button with icon and text you can change it to fit your needs.

MyButton.qml:

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import Qt.labs.platform 1.0
import QtLocation 5.12
import QtQuick.Controls.Material 2.15


MouseArea {
    id: control
    width: control.w
    height: control.h
    property string icon_btn
    property bool icon_visible: true
    property string text
    property int border: 3
    property string borderColor: "white"
    property string colorr: "#222222"
    property int w: 50
    property int h: 50
    property bool text_visible: true
    property bool clicked: false
    property int radius: 12
    property int contentLeftMargin: 0
    property string buttonColor: enabled ? control.colorr : "grey"

    cursorShape: Qt.PointingHandCursor

    Rectangle {
        border.color: control.borderColor
        border.width: control.border
        radius: control.radius
        anchors.fill: parent
        color: control.buttonColor

        RowLayout{
            anchors.fill: parent

            Item { Layout.fillWidth: true }
            Image{
                id: img
                visible: control.icon_visible
                source: control.icon_btn
                Layout.preferredWidth: 35
                Layout.preferredHeight: 35
                //Layout.leftMargin: control.contentLeftMargin
            }
            Text{
                id: txt
                text: control.text
                font.pointSize: 17
                font.bold: true
                color: "white"
                verticalAlignment: Text.AlignVCenter
                horizontalAlignment: Text.AlignHCenter
                visible: control.text_visible ? x   width   15 < control.width : 0
                //Layout.leftMargin: control.contentLeftMargin
            }
            Item { Layout.fillWidth: true }
        }
    }
    Layout.bottomMargin: 10
}

Then use it in your main qml file.

For example:

Window {

    MyButton{
        id: btn_refresh
        icon_btn: "qrc:/Icons/outline_refresh_white_48pt_3x.png"
        
        onClicked: {
            //do something on click
        }
    }
}

  • Related