2

I'm trying to write simple QML application, which will consist of many repeated elements, organized in rows. The outcome will be similar to the one presented below: enter image description here

Currently, I have a repetitive piece of code which achieves this goal:

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5
import QtQuick.Controls.Material 2.3
import QtQuick.Layouts 1.12

ApplicationWindow {
    Material.theme: Material.Dark
    visible: true
    width: 480
    height: 640
    title: qsTr("Hello world!")
    id: root

    GridLayout {
        anchors.horizontalCenter: parent.horizontalCenter
        columns: 3

        Text {
            color: "white"
            text: "aaa"
            font.family: "Ubuntu"
            font.pixelSize: 20
        }
        SpinBox {
            from: 0
            to: 1000
            stepSize: 1
            editable: true
        }
        Rectangle {
            width: 40
            height: 20
            color: "#F48FB1"
            Text {
                font.family: "Ubuntu"
                font.pixelSize: 16
                text: "ml"
                anchors.verticalCenter: parent.verticalCenter
                anchors.horizontalCenter: parent.horizontalCenter
            }
        }

        Text {
            color: "white"
            text: "bbb"
            font.family: "Ubuntu"
            font.pixelSize: 20
        }
        SpinBox {
            from: 0
            to: 100
            stepSize: 1
            editable: true
        }
        Rectangle {
            width: 40
            height: 20
            color: "#F48FB1"
            Text {
                font.family: "Ubuntu"
                font.pixelSize: 16
                text: "%"
                anchors.verticalCenter: parent.verticalCenter
                anchors.horizontalCenter: parent.horizontalCenter
            }
        }
        Text {
            color: "white"
            text: "ccc"
            font.family: "Ubuntu"
            font.pixelSize: 20
        }
        SpinBox {
            from: 0
            to: 100
            stepSize: 1
            editable: true
        }
        Rectangle {
            width: 40
            height: 20
            color: "#F48FB1"
            Text {
                font.family: "Ubuntu"
                font.pixelSize: 16
                text: "%"
                anchors.verticalCenter: parent.verticalCenter
                anchors.horizontalCenter: parent.horizontalCenter
            }
        }
    }
}

However, every row has exactly the same structure, so I tried to extract the component from the code:

Item {
id: ingredient
property alias ingredientText: qualifier.text
property alias ingredientMaxValue: amount.to
property alias ingredientUnit: unit.text

RowLayout {
    Text {
        id: qualifier
        color: "white"
        text: "asdf"
        font.family: "Ubuntu"
        font.pixelSize: 20
    }
    SpinBox {
        id: amount
        from: 0
        to: 1000
        stepSize: 1
        editable: true
    }
    Rectangle {
        width: 40
        height: 20
        color: "#F48FB1"
        Text {
            id: unit
            font.family: "Ubuntu"
            font.pixelSize: 16
            text: "unit"
            anchors.verticalCenter: parent.verticalCenter
            anchors.horizontalCenter: parent.horizontalCenter
            }
        }
    }
}

Unfortunately, when I try to use my component in the main window, it is misaligned and gets out of visible part of it (I can see it again after maximizing the window):

ApplicationWindow {
Material.theme: Material.Dark
visible: true
width: 480
height: 640
title: qsTr("Hello world!")
id: root

GridLayout { // I know now it will not work properly for sure,
    //  but i tried using other layouts and alignment methods
    //  and it didn't help me at all
    anchors.horizontalCenter: parent.horizontalCenter
    columns: 3
    Ingredient {
        ingredientMaxValue: 100; ingredientText: "qwerty"; ingredientUnit: "kg"
        }
    }
}

enter image description here

The question is: how can I achieve items alignment like in the first picture, using "Ingredient" components?

Rozek
  • 53
  • 10
  • 1
    The root `Item` of your component has no size i.e. its size is 0 so layout places it in such a strange way. That besides the fact that this item is completely useless here. – folibis May 05 '19 at 11:50

2 Answers2

2

You have the following errors:

  • The size of your children is not taken to calculate the size of the item. To calculate the right size you can use the implicitWidth and implicitHeight of the RowLayout.
  • You must not use GridLayout because as you point out each Ingredient is an element, in this case you must use ColumnLayout.

Ingredient.qml

import QtQuick 2.0
import QtQuick.Layouts 1.12
import QtQuick.Controls 2.5

Item {
    id: ingredient
    property alias ingredientText: qualifier.text
    property alias ingredientMaxValue: amount.to
    property alias ingredientUnit: unit.text

    width: rl.implicitWidth
    height: rl.implicitHeight

    RowLayout {
        id: rl
        Text {
            id: qualifier
            color: "white"
            text: "asdf"
            font.family: "Ubuntu"
            font.pixelSize: 20
        }
        SpinBox {
            id: amount
            from: 0
            to: 1000
            stepSize: 1
            editable: true
        }
        Rectangle {
            width: 40
            height: 20
            color: "#F48FB1"
            Text {
                id: unit
                font.family: "Ubuntu"
                font.pixelSize: 16
                text: "unit"
                anchors.verticalCenter: parent.verticalCenter
                anchors.horizontalCenter: parent.horizontalCenter
            }
        }
    }
}

main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5
import QtQuick.Controls.Material 2.3
import QtQuick.Layouts 1.12

ApplicationWindow {
    Material.theme: Material.Dark
    visible: true
    width: 480
    height: 640
    title: qsTr("Hello world!")
    id: root

    ColumnLayout{
        width: parent.width
        height: implicitHeight
        Ingredient{
            Layout.alignment: Qt.AlignHCenter
            ingredientMaxValue: 100; ingredientText: "qwerty"; ingredientUnit: "kg"
        }
        Ingredient{
            Layout.alignment: Qt.AlignHCenter
            ingredientMaxValue: 100; ingredientText: "qwerty"; ingredientUnit: "kg"
        }
        Ingredient{
            Layout.alignment: Qt.AlignHCenter
            ingredientMaxValue: 100; ingredientText: "qwerty"; ingredientUnit: "kg"
        }
    }

}

enter image description here

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
1

Problem was in anchors. You should read about it, it will help you in the future. You can try to experiment with anchors to take the best positioning for you.

Briefly about anchors. Anchors will automaticly set the position for item adjusting to the screen. Also I'd recomend to read about Column, Row and Grid.

enter image description here

ApplicationWindow {
    Material.theme: Material.Dark
    visible: true
    width: 480
    height: 640
    title: qsTr("Hello world!")
    id: root

    GridLayout {
        anchors.fill: parent
        columns: 3
        Item {
            id: ingredient
            anchors.fill: parent

            property alias ingredientText: qualifier.text
            property alias ingredientMaxValue: amount.to
            property alias ingredientUnit: unit.text

            RowLayout {
                anchors.right: parent.right
                anchors.left: parent.left
                anchors.top: parent.top
                Text {
                    id: qualifier
                    color: "white"
                    text: "asdf"
                    font.family: "Ubuntu"
                    font.pixelSize: 20
                }
                SpinBox {
                    id: amount
                    from: 0
                    to: 1000
                    stepSize: 1
                    editable: true
                }
                Rectangle {
                    width: 40
                    height: 20
                    color: "#F48FB1"
                    Text {
                        id: unit
                        font.family: "Ubuntu"
                        font.pixelSize: 16
                        text: "unit"
                        anchors.verticalCenter: parent.verticalCenter
                        anchors.horizontalCenter: parent.horizontalCenter
                    }
                }
            }
        }
    }
}
BrutalWizard
  • 495
  • 1
  • 9
  • 19