0
votes

I'm trying to make an equivalent to wpf stackpanel, I already had a logic and implemented it but something is wrong about width, I don't know how to create new components without getting into width loop binding, here is my stackpanel:

StackPanel.qml

import QtQuick 2.12
import QtQuick.Controls 2.12
import KiMa.Models 1.0
Item {
    id:root
    property var orientation : UOrientation.Horizontal
    property int itemSpacing : 10
    default property list<Item> pageData
    Loader{
        property var childs
        anchors.fill: parent
        id:loader
        onChildsChanged: {
            if(root.pageData != null){
                for(var z = 0;z<root.pageData.length;++z){
                    root.pageData[z].parent = loader.childs
                }
            }
        }

    }
    state: orientation == UOrientation.Horizontal ? "row": "col"
    states: [
        State {
            name: "row"
            PropertyChanges {
                target: loader
                sourceComponent : row
            }
        },
        State{
            name: "col"
            PropertyChanges {
                target: loader
                sourceComponent : col
            }
        }

    ]
    Component{
        id:col
        Column{
            Component.onCompleted: {
                childs = _col;
            }
            id:_col
            width: parent.width
            spacing: root.itemSpacing
        }
    }
    Component{
        id:row
        Row{
            Component.onCompleted: {
                childs = _row
            }
            id:_row
            width: parent.width
            layoutDirection: Qt.RightToLeft
            spacing: root.itemSpacing
        }
    }
}

and my orientation enum is like this:

#ifndef UORIENTATION_H
#define UORIENTATION_H
#include<QObject>

class UOrientation
{
    Q_GADGET
public:
    explicit UOrientation();
    enum Orientation{
        Horizontal,
        Vertical
    };
    Q_ENUM(Orientation)
};

#endif // UORIENTATION_H

and usage example should be like this:

StackPanel{
    x: 320
    height: 50
    anchors.horizontalCenter: parent.horizontalCenter
    anchors.bottom: parent.bottom
    anchors.bottomMargin: 25
    Button{

    }
    Button{

    }
}

you need to add this into main.cpp:

qmlRegisterUncreatableType<UOrientation>("KiMa.Models",1,0,"UOrientation","its not creatable type!");

This code is working , if you have anything to suggest me to change or you think I made a mistake let me know, the only problem I can see here is width binding.

I already tried using childrenRect but it is not working:

width: childrenRect.width
height: childrenRect.height

Note : stackpanel allowing you to stack item after item on top of each other you can set orientation to horizontal or vertical so in qt its a column and row together which i made it already.
vertical one : a vertical stack panel
horizontal one :
a horizontal stack panel

1
Many do not know how a stackpanel wpf looks or works, you could show a picture of what you want to geteyllanesc
@eyllanesc i added a note about stackpanelMahdi Khalili
Do you need to change dynamically the orientation of the "StackPanel"? If you don't you could just use a Row or a Column.GrecKo
i dont want to use Row and Column at all so i created Stackpanel so i can set its orientation and it creates me row and colMahdi Khalili
Would using GridLayout be an alternative? You can change the number of rows/cols and/or change the flow of the layout depending on your needs. doc.qt.io/qt-5/qml-qtquick-layouts-gridlayout.htmlMailerdaimon

1 Answers

4
votes

You can do this easily with a Grid by setting the number of columns. If you want a separate component, you can create your StackPanel.qml with the following:

import QtQuick 2.0

Grid {
    property int orientation: Qt.Horizontal
    columns: orientation === Qt.Horizontal ? -1 : 1
}

QML StackPanel

If you want a scrollable object, you could also use a ListView with an ObjectModel model. ListView has an orientation property.