Search code examples
qmlqt5qtquick2qtquickcontrolsqtquickextras

Unable to position custom styled Tumbler


I am trying to give a Tumbler my own style. I declare the Tumbler like this:

Tumbler {
    style: MyTumblerStyle {}
    height: UIConstants.smallFontSize * 10
    width: UIConstants.smallFontSize * 3

    TumblerColumn {
        model: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]
    }
}

where MyTymblerStyle is defined like this:

TumblerStyle {
    id: root
    visibleItemCount: 5
    background: Rectangle {}
    foreground: Item {}

    frame: Item {}

    highlight: Item {}
    delegate: Item {
        id: delRoot
        implicitHeight: (control.height) / root.visibleItemCount
        Item {
            anchors.fill: parent

            Text {
                text: styleData.value
                font.pixelSize: UIConstants.smallFontSize
                font.family: UIConstants.robotoregular
                anchors.centerIn: parent
                scale: 1.0 + Math.max(0, 1 - Math.abs(styleData.displacement)) * 0.6
                color: styleData.current?UIConstants.color:"black"
                opacity: 1 - Math.abs(styleData.displacement/(root.visibleItemCount-3))
            }
        }
    }

}

I use it in a Row like this:

Row {
    MyTumbler {}
    StandardText {
        color: UIConstants.color
        text: "Uhr"
    }
}

Now, the result looks like this:

Screenshot

As you can see, the "Uhr" text center is aligned to the top of the Tumbler. Also the Row does not seem to recognize the real width of the Tumbler.

Why? It does work when I do not use MyTumblerStyle.


Solution

  • The problem isn't your style, it's the width assignment.

    It helps to break out the Rectangles at a time like this:

    import QtQuick 2.4
    import QtQuick.Controls 1.3
    import QtQuick.Extras 1.3
    
    ApplicationWindow {
        title: qsTr("Hello World")
        width: 300
        height: 600
        visible: true
    
        Column {
            anchors.centerIn: parent
    
            Tumbler {
                id: tumbler
                width: 30
    
                TumblerColumn {
                    model: 25
                }
    
                Component.onCompleted: print(width, height, implicitWidth, implicitHeight)
            }
    
            Rectangle {
                width: tumbler.implicitWidth
                height: tumbler.implicitHeight
                color: "transparent"    
                border.color: "blue"
    
                Text {
                    text: "Tumbler implicit size"
                    anchors.fill: parent
                    wrapMode: Text.Wrap
                }
            }
    
            Rectangle {
                width: tumbler.width
                height: tumbler.height
                color: "transparent"
                border.color: "blue"
    
                Text {
                    text: "The size you gave"
                    anchors.fill: parent
                    wrapMode: Text.Wrap
                }
            }
        }
    }
    

    (I don't have access to UIConstants, so I guess the width you set)

    tumbler illustration

    The implicitWidth of Tumbler is calculated based on the width of each individual TumblerColumn. This allows you to set individual widths for columns, something that is necessary for scenarios where some are wider than others, for example:

    tumbler date picker

    So, you should also set the width of your column, or, preferably, only set the width of your column, and not the entire Tumbler:

    import QtQuick 2.4
    import QtQuick.Controls 1.3
    import QtQuick.Extras 1.3
    
    ApplicationWindow {
        width: 300
        height: 600
        visible: true
    
        Row {
            anchors.centerIn: parent
    
            Tumbler {
                id: tumbler
    
                TumblerColumn {
                    model: 25
                    width: 30
                }
            }
            Text {
                text: "Uhr"
            }
        }
    }
    

    This also explains why the Text is weirdly positioned; the Row sees 30 pixels, but the column still has its original (much wider) width.