Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Qt Quick Controls 2 SpinBox customization



  • I have used the Qt Quick Controls templates to customize a few controls, but I'm stuck with the SpinBox. I used the example code at Customizing Qt Quick Controls 2.

    The problem is that the up & down button clickable areas are a few pixels wide on the outer edges of the two buttons. I can't figure out why this is happening. Hopefully, it is not a QML bug!

    import QtQuick 2.12
    import QtQuick.Templates 2.12 as T
    
    T.SpinBox {
        id: control
        value: 50
        editable: true
    
        contentItem:
            TextInput {
            z: 2
            text: control.textFromValue(control.value, control.locale)
            anchors.fill: parent
            font: control.font
            color: "#21be2b"
            selectionColor: "#21be2b"
            selectedTextColor: "#ffffff"
            horizontalAlignment: Qt.AlignHCenter
            verticalAlignment: Qt.AlignVCenter
    
            readOnly: !control.editable
            validator: control.validator
            inputMethodHints: Qt.ImhFormattedNumbersOnly
        }
    
        up.indicator: Rectangle {
            x: control.mirrored ? 0 : parent.width - width
            height: parent.height
            implicitWidth: 40
            implicitHeight: 40
            color: control.up.pressed ? "#e4e4e4" : "#f6f6f6"
            border.color: enabled ? "#21be2b" : "#bdbebf"
    
            Text {
                text: "+"
                font.pixelSize: control.font.pixelSize * 2
                color: "#21be2b"
                anchors.fill: parent
                fontSizeMode: Text.Fit
                horizontalAlignment: Text.AlignHCenter
                verticalAlignment: Text.AlignVCenter
            }
        }
    
        down.indicator: Rectangle {
            x: control.mirrored ? parent.width - width : 0
            height: parent.height
            implicitWidth: 40
            implicitHeight: 40
            color: control.down.pressed ? "#e4e4e4" : "#f6f6f6"
            border.color: enabled ? "#21be2b" : "#bdbebf"
    
            Text {
                text: "-"
                font.pixelSize: control.font.pixelSize * 2
                color: "#21be2b"
                anchors.fill: parent
                fontSizeMode: Text.Fit
                horizontalAlignment: Text.AlignHCenter
                verticalAlignment: Text.AlignVCenter
            }
        }
    
        background: Rectangle {
            implicitWidth: 140
            border.color: "#bdbebf"
        }
    
        implicitWidth: Math.max(background ? background.implicitWidth : 0, contentItem.implicitWidth + leftPadding + rightPadding)
        implicitHeight: Math.max(background ? background.implicitHeight : 0, contentItem.implicitHeight + topPadding + bottomPadding)
        leftPadding: 4
        rightPadding: 4
    }
    
    


  • Hi, this seems to work nicely with a few changes to your code;

    I've purposely left in the apparently unnecessary code for your comparison, hope it helps . . .

    /*import QtQuick 2.12*/
    /*import QtQuick.Templates 2.12 as T*/
    
    /*T.SpinBox {*/
    
    import QtQuick 2.6
    import QtQuick.Controls 2.0
    
    SpinBox {
        id: control
        value: 50
        editable: true
    
        contentItem: TextInput {
            z: 2
            text: control.textFromValue(control.value, control.locale)
    
            /*anchors.fill: parent*/
    
            font: control.font
            color: "#21be2b"
            selectionColor: "#21be2b"
            selectedTextColor: "#ffffff"
            horizontalAlignment: Qt.AlignHCenter
            verticalAlignment: Qt.AlignVCenter
    
            readOnly: !control.editable
            validator: control.validator
            inputMethodHints: Qt.ImhFormattedNumbersOnly
        }
    
        up.indicator: Rectangle {
            x: control.mirrored ? 0 : parent.width - width
            height: parent.height
            implicitWidth: 40
            implicitHeight: 40
            color: control.up.pressed ? "#e4e4e4" : "#f6f6f6"
            border.color: enabled ? "#21be2b" : "#bdbebf"
    
            Text {
                text: "+"
                font.pixelSize: control.font.pixelSize * 2
                color: "#21be2b"
                anchors.fill: parent
                fontSizeMode: Text.Fit
                horizontalAlignment: Text.AlignHCenter
                verticalAlignment: Text.AlignVCenter
            }
        }
    
        down.indicator: Rectangle {
            x: control.mirrored ? parent.width - width : 0
            height: parent.height
            implicitWidth: 40
            implicitHeight: 40
            color: control.down.pressed ? "#e4e4e4" : "#f6f6f6"
            border.color: enabled ? "#21be2b" : "#bdbebf"
    
            Text {
                text: "-"
                font.pixelSize: control.font.pixelSize * 2
                color: "#21be2b"
                anchors.fill: parent
                fontSizeMode: Text.Fit
                horizontalAlignment: Text.AlignHCenter
                verticalAlignment: Text.AlignVCenter
            }
        }
    
        background: Rectangle {
            implicitWidth: 140
            border.color: "#bdbebf"
        }
        /*
        implicitWidth: Math.max(background ? background.implicitWidth : 0, contentItem.implicitWidth + leftPadding + rightPadding)
        implicitHeight: Math.max(background ? background.implicitHeight : 0, contentItem.implicitHeight + topPadding + bottomPadding)
        leftPadding: 4
        rightPadding: 4
        */
    }
    
    


  • Hi, you say this works for you. How did you run the code? The modified code doesn't work for me. I used the SpinBox in another QML page and with the changed code, nothing happens.

    The idea is to customize a component, which I'm doing by making use of the template. The code I posted actually works, the only problem is that the size of the TextInput component overlaps a large percentage of the up and down indicators.

    Ok, I found the problem by studying the Qt source! The leftPadding and rightPadding properties should include the width of the left and right indicators and the padding property contains the gutter/margin, which I thought was the purpose of leftPadding and rightPadding.

    leftPadding: padding + (control.mirrored ? (up.indicator ? up.indicator.width : 0) : (down.indicator ? down.indicator.width : 0))
    rightPadding: padding + (control.mirrored ? (down.indicator ? down.indicator.width : 0) : (up.indicator ? up.indicator.width : 0))
    

    Fixes the calculation of the width of the control to accomodate the TextEntry and up and down indicators.


Log in to reply