Search code examples
qmlpyside6

QML issues with nested layouts


I have an issue with nested layouts. In the MRE below, the last ComboBox in Item1 just sits on top of the two other elements of the layout. I have tried adding 'anchors.fill: parent' to the main layouts of all items, but it didn't help. I also tried placing the ComboBox in a ColumnLayout on its own, or in an Item on its own, or in a ColumnLayout inside an Item, but none helped. Here is the MRE:

main.py

import sys
from pathlib import Path
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine


if __name__ == "__main__":
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()
    qml_file = Path(__file__).resolve().parent / "main.qml"
    engine.load(qml_file)
    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec())

main.qml

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

ApplicationWindow {
    id: mainWindow
    width: 900
    height: 600
    visible: true

    StackLayout {
        id: mainStack
        anchors.fill: parent
        anchors.margins: 20

        Item1 {}
    }
}

Item1.qml

Item {

    ColumnLayout {

        GridLayout {
            columns: 2

            Label {
                text: "label"
            }

            Switch {
                id: mode
                text: "switch"
            }
        }

        StackLayout {
            currentIndex: mode.checked ? 1 : 0

            Item2 {}

            Item3 {}
        }

        ComboBox {}
    }
}

Item2.qml

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

Item {
    GridLayout {
        columns: 2

        Label {
            text: "label - item 2"
        }

        ComboBox {}
    }
}

Item3.qml

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

Item {
    GridLayout {
        columns: 2

        Label {
            text: "label - item 3"
        }

        ComboBox {}
    }
}

I am using the following:

Python version: 3.11.1

PySide version: 6.5.0

OS: MacOS 13.2.1


Solution

  • I think the problem is that all the Items[1,2,3] have zero width and height, try to set their clip property to true and all their children will disappear.

    At first declare how the Item1 in main.qml should be placed ie:

    Item1 {
      Layout.fillWidth: true
      Layout.fillHeight: true
    }
    

    Then in every ItemX.qml file either specify the root Item's implicit width and height as the ColumnLayout's implicitWidth and implicitHeight and resize the ColumnLayout to full Item's width and height, ie:

    // Item1.qml
    Item {
       implicitWidth: layout.implicitWidth
       implicitHeight: layout.implicitHeight
    
       ColumnLayout {
          id: layout
          anchors.fill: parent
       }
    }
    

    or just get rid of the root Item:

    // Item1.qml
    ColumnLayout {
      id: layout
    }
    

    Haven't test it but that should work.