Search code examples
qtqmlgroupbox

How to align groupbox horizontally centered along with scroll view in qml


I am facing trouble in aligning group boxes to horizontally centered along with scrollview in Qml.

I have tried anchors.horizontalCentre: Qt.AlignHCenter and Layout.alignment: Qt.AlignHCenter. But none of them works. Please find below sample code which aligns horizontally left.

ApplicationWindow {
id: root
width: 500
height: 100
visible: true

ScrollView {
    anchors.fill: parent
    clip: true
    ScrollBar.vertical.policy: ScrollBar.AlwaysOn

    ColumnLayout { //Arrange GroupBox's in column wise
        anchors.fill: parent
        spacing: 10
        anchors.margins: 10
        Layout.alignment: Qt.AlignHCenter

        GroupBox {
            title: qsTr("Sample1")

            ColumnLayout { //Arrange child Items in column wise
                Text { id: gr1text1; text: qsTr("Group 1, Text 1") }
                Text { id: gr1text2; text: qsTr("Group 1, Text 2") }
            }
        }

        GroupBox {
            title: qsTr("Sample2")

            ColumnLayout { //Arrange child Items in column wise
                Text { id: gr2text1; text: qsTr("Group 2, Text 1") }
                Text { id: gr2text2; text: qsTr("Group 2, Text 2") }
            }
        }
    }
}
}

The output of the above code is captured below

enter image description here


Solution

  • I did a couple of changes:

    1. Replace ScrollView with Flickable
    2. Configure the Flickable to take the width from the children, but, the height from the parent item. We do this, because you indicated the need for a vertical ScrollBar so the height cannot be taken from the children
    3. Configure the Flickable to have the anchors for horizontal alignment
    4. Apply ScrollBar.vertical to Flickable and set the width to 20 pixels for a fat scrollbar
    5. Set the contentWidth and contentHeight to the parent ColumnLayout. Doing this helps the ScrollBar work out the geometry of the content versus the geometry of the Flickable
    import QtQuick
    import QtQuick.Controls
    import QtQuick.Layouts
    Page {
        Flickable {
            id: flickable
            anchors.fill: parent
            clip: true
            contentWidth: columnLayout.width
            contentHeight: columnLayout.height
            ScrollBar.vertical : ScrollBar {
                width: 20
                policy: ScrollBar.AlwaysOn
            }
            ColumnLayout {
                id: columnLayout
                width: flickable.width
                spacing: 10
                GroupBox {
                    Layout.alignment: Qt.AlignHCenter
                    title: qsTr("Sample1")
                    ColumnLayout { //Arrange child Items in column wise
                        Text { id: gr1text1; text: qsTr("Group 1, Text 1") }
                        Text { id: gr1text2; text: qsTr("Group 1, Text 2") }
                    }
                }
                GroupBox {
                    Layout.alignment: Qt.AlignHCenter
                    title: qsTr("Sample2")
                    ColumnLayout { //Arrange child Items in column wise
                        Text { id: gr2text1; text: qsTr("Group 2, Text 1") }
                        Text { id: gr2text2; text: qsTr("Group 2, Text 2") }
                    }
                }
            }
        }
    }
    

    You can Try it Online!

    Also, consider using ListView since it has a natural ability to apply a ScrollBar. The following example demonstrates how your example can be expressed using a ListView with a model:

    import QtQuick
    import QtQuick.Controls
    import QtQuick.Layouts
    Page {
        ListView {
            anchors.fill: parent
            width: contentItem.childrenRect.width + 20
            height: parent.height
            model: [ {
                title: qsTr("Sample 1"),
                text1: qsTr("Group 1, Text 1"),
                text2: qsTr("Group 1, Text 2")
            }, {
                title: qsTr("Sample 2"),
                text1: qsTr("Group 2, Text 1"),
                text2: qsTr("Group 2, Text 2")
            } ]
            clip: true
            spacing: 10
            ScrollBar.vertical: ScrollBar {
                policy: ScrollBar.AlwaysOn
                width: 20
            }
            delegate: GroupBox {
                anchors.horizontalCenter: parent.horizontalCenter
                title: modelData.title
                ColumnLayout {
                    Text { text: modelData.text1 }
                    Text { text: modelData.text2 }
                }
            }
        }
    }
    

    You can Try it Online!