Search code examples
qtqml

How to fill the width of a parent element


I have a problem, which can be seen on the attached screenshot

enter image description here

There is ApplicationWindow, which has header and ListView which is used in horizontal layout. Each item of list should be one page of application. Unfortunatelly, the width of base page is not set correctly to fill width of its parent (white background, not the grey one).

Here is the code of main page, it should load Login page - it is shown on the image.

ApplicationWindow {
    id: root_window
    title: Style.applicationName
    visible: true
    color: "white"
    width: Style.windowWidth
    height: Style.windowHeight    

    ColumnLayout {
        id: root_layout
        spacing: 0
        width: root_window.width
        height: root_window.height

        SmonHeader {
            id: smon_user_app_header
            height: Style.headerHeight
            anchors.top: parent.top
            Layout.alignment: Qt.AlignLeft
            Layout.fillWidth: true
        }

        Component.onCompleted: {
            console.log("Main width: " + width);
        }

        ListView {
            id: navigation

            width: parent.width
            height: parent.height
            orientation: ListView.Horizontal
            interactive: true // disable manual pageChange

            snapMode: ListView.SnapOneItem // while moving to right, finish move
            highlightRangeMode: ListView.StrictlyEnforceRange // mouse gesture make currentIndex change
            highlightMoveDuration: 400 // speed up pages change (swap)

            model: ObjectModel {
                /* First page with login capabilities */
                Login {
                    id: login_module
                    width: root_layout.width
                    height: root_layout.height
                }
            }
        }
    }

    /* Private function definition*/
    function init_database()
    {
        var database = Storage.LocalStorage.openDatabaseSync(Style.databaseName, Style.databaseVersion, Style.databaseDescr, Style.databaseSize);
        smonDatabase.startDatabase(Style.databaseName);
    }

    Component.onCompleted: {
        init_database();
    }
}

Here is the base of Login page:

import QtQuick 2.4
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2

import "../"
import "./common"

Rectangle {
    id: login_page
    // why parent.width is not set ?
    anchors.fill: parent
    //width: parent.width
    //Layout.fillWidth: true

    property string credentials_title: qsTr("Přístupové údaje")
    property string available_devices: qsTr("Dostupné servery")
    property string identity_title: qsTr("Identita")
    property string password_title: qsTr("Heslo")
    property string domain_title: qsTr("Doména")
    property string infoLine_title: qsTr("Zapamatovat přihlašovací údaje")
    property string username_title: qsTr("Jméno");

    Component.onCompleted: {
        console.log("Login width: " + login_page.width);
        control.cancelEnabled = false
    }

    ColumnLayout{
        id: navigation
        spacing: Style.spacing
        anchors.left: parent.left
        anchors.leftMargin: Style.defaultAnchors
        Layout.fillWidth: true
        anchors.fill: parent
        width: parent.width

        Text {
            id: title
            //anchors.top: parent.top
            //anchors.left: parent.left
            font.pointSize: Style.fontSizeHeading

            text: credentials_title
        }

        ColumnLayout{
            id: navigationLogin
            spacing: Style.spacing
            anchors.left: parent.left
            anchors.leftMargin: Style.defaultAnchors
            Layout.fillWidth: true
            Layout.bottomMargin: Style.bottomMargin
            width: (parent.width - 4*Style.defaultAnchors)

            GridLayout {
                id: input_login
                rowSpacing: Style.denseSpacing
                columns: 2
                columnSpacing: Style.spacing
                anchors.left: parent.left
                anchors.leftMargin: Style.defaultAnchors
                width: 200

                Text {
                    id: user_name
                    font.pointSize: Style.fontSizeSubHeading

                    text: username_title
                }

                SmonComboBox {
                    id: user
                    width: parent.width

                    value: smonRole.user
                    object: smonRole
                    prop: "user"
                    isEditable: true
                    dataModel: smonRole.userData
                    selectedIndex: smonRole.userNameSelected
                }

                Text {
                    id: password_name
                    font.pointSize: Style.fontSizeSubHeading

                    text: password_title
                }

                SmonTextField {
                    id: password
                    width: parent.width
                    type: "password"

                    object: smonRole
                    prop: "pass"
                    value: smonRole.pass

                    onEnterPressed: {
                        user.enabled = false
                        password.enabled = false
                        //control.okEnabled = false
                        control.okEnabled = false
                        control.cancelEnabled = true

                        smonRole.save();
                        smonCommunication.connect();
                    }

                    onValueChanged: {
                        if(password.value !== "")
                        {
                            control.okEnabled = true
                        }
                        else
                        {
                            control.okEnabled = false
                        }

                    }
                }
            }

            ColumnLayout {
                id: scanning
                spacing: Style.denseSpacing
                anchors.left: parent.left
                //Layout.fillWidth: true



                RowLayout {
                    id: slider_component

                    Text {
                        id: scanningHeader
                        font.pointSize: Style.fontSizeSubHeading

                        text: qsTr("Perioda vyhledávání zařízení");
                    }

                    Text {
                        id: value
                        font.pointSize: Style.fontSizeInfo
                        anchors.left: scanningHeader.right
                        anchors.leftMargin: Style.defaultAnchors
                        width: 30

                        text: slider.value
                    }
                }

                Slider {
                    id: slider
                    minimumValue: 2
                    maximumValue: 30
                    Layout.fillWidth: true
                    stepSize: 1

                    value: smonCommunication.scanPeriod

                    onValueChanged: {
                        smonCommunication.scanPeriod = slider.value;
                    }
                }
            }

            SmonControlPanel {
                id: control
                width: parent.width
                okEnabled: smonRole.user != "" && smonRole.pass != ""
                okVisible: true
                cancelVisible: true

                onSignalOk: {
                    // hide content
                    user.enabled = false
                    password.enabled = false
                    control.okEnabled = false
                    control.cancelEnabled = true

                    smonRole.save();
                    smonCommunication.connect();
                }

                onSignalCancel: {
                    // show content again
                    password.enabled = true
                    user.enabled = true
                    //domain.enabled = true
                    control.cancelEnabled = false
                    control.okEnabled = true

                    //smonConnection.logout();
                    smonCommunication.disconnect();
                    smonRole.disconnected();
                }
            }
        }

        Text {
            id: favourite
            font.pointSize: Style.fontSizeHeading

            text: available_devices
        }

        ListView{
            id: servers
            Layout.fillHeight: true
            width: parent.width

            model: smonCommunication.devicesList

            delegate: Rectangle {
                id: serverList
                height: 80
                width: parent.width

                ColumnLayout{
                    Text {
                        id: serverName
                        text: modelData.bluetooth_name
                    }

                    Text {
                        id: rssi
                        text: modelData.bluetooth_rssi
                    }
                }

                MouseArea {
                    id: bt_device
                    anchors.fill: parent

                    onClicked: {
                        if(smonCommunication.btCanConnect === true)
                            smonCommunication.connect(index);
                    }
                }
            }
        }
    }

    MessageDialog {
        id: errorDialog
        standardButtons: StandardButton.Cancel | StandardButton.OK
        visible: false;

        informativeText: smonCommunication.errorMessage

        onInformativeTextChanged: {
            errorDialog.visible = true;
        }
    }
}

Is there problem on the main page or on the page which is loaded?


Solution

  • Your problem lies with the anchors.fill: parent bit in your ObjectModel.

    The parent here, is not the ListView, but the ListView's contentItem, which happens to have an implicit width of 100px.

    In your minimal example, something like this should work:

    model: ObjectModel {
        /* First page with login capabilities */
        Rectangle{
            id: one
            //anchors.fill: parent <- parent is not navigation
            width: navigation.width
            height: 50
            color: "red"
        }
    }
    

    Generally speaking, you should not use the parent property in your delegates.