Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to determine total size needed by QML scene?



  • I display the following QML file inside a QQuickView:

    import QtQuick 2.0
    import QtQuick.Layouts 1.12
    import QtQml 2.12
    
    Item 
    {
        ColumnLayout
        {
            anchors.fill: parent
            Text
            {
                text: "First row"
            }
            Text
            {
                text: "Second row"
            }
            Text
            {
                text: "Third row"
            }
        }
    }
    

    How do I determine on the C++ side how much size the QML scene needs in order to display fully (without scaling)?

    In the QQuickView::statusChanged signal with status "Ready", I get

    • Null size for QQuickView::initialSize()
    • the current size of the view for QQuickView::size() , not the size needed to display
    • Invalid size for renderTargetSize()

    EDIT: Also contentItem().implicitWidth / Height or .size() are null sizes



  • @Asperamanca You have to use implicitHeight and implicitWidth from the ColumnLayout component, like this:

    import QtQuick 2.0
    import QtQuick.Layouts 1.12
    import QtQml 2.12
    
    Item 
    {
        implicitWidth: _layout.implicitWidth
        implicitHeight: _layout.implicitHeight
           
        ColumnLayout
        {
            id: _layout
            ...
        }
        Component.onCompleted: {
            console.log("Preferred size: " + _layout.implicitWidth + "x" + _layout.implicitHeight);
        }
    }
    

  • Qt Champions 2018

    Why do you use Item as a root with a single child?



  • @KroMignon said in How to determine total size needed by QML scene?:

    @Asperamanca You have to use implicitHeight and implicitWidth from the ColumnLayout component, like this:

    import QtQuick 2.0
    import QtQuick.Layouts 1.12
    import QtQml 2.12
    
    Item 
    {
        implicitWidth: _layout.implicitWidth
        implicitHeight: _layout.implicitHeight
           
        ColumnLayout
        {
            id: _layout
            ...
        }
        Component.onCompleted: {
            console.log("Preferred size: " + _layout.implicitWidth + "x" + _layout.implicitHeight);
        }
    }
    

    EDIT: If that's what I need to do (and I don't have reason to doubt you): Why does it display correctly and doesn't show any warnings at design time?



  • @GrecKo said in How to determine total size needed by QML scene?:

    Why do you use Item as a root with a single child?

    It used to hold more than that. But my C++ code should still be able to figure out how big the scene is, ideally...



  • @Asperamanca said in How to determine total size needed by QML scene?:

    If that's what I need to do (and I don't have reason to doubt you): Why does it display correctly and doesn't show any warnings at design time?

    I am not sure to really understand your questionings, I hope my reply is not out of scope!

    I set up implicitWidth and implicitHeight of the top component, so if width/height are not defined, those values will be use are size for the item.
    ColumnLayout (and RowLayout or GridLayout) is updating his implicitWidth/implicitHeight according to all items which it is holding.

    This is how it works, of course if you are using anchors.

    I don't understand your question about warnings? Do you have warnings or do you expect warnings?



  • @KroMignon
    Ah, I think I understand (but please correct me if I'm wrong): There is no rule saying that the root component has to be big enough to contain all it's children. It just would look bad e.g. if the root component was a rectangle, and you would try to fill the background...



  • @Asperamanca said in How to determine total size needed by QML scene?:

    There is no rule saying that the root component has to be big enough to contain all it's children

    There are some aspect to know about QML:

    • root component size has not link with the elements in side it.
    • an Item can contains elements which are outside from visible space (eg. x > root.width or y >root.height)
    • all component for which visible = true are rendered, even if they are not visible because out of visible space or opacity = 0

    ==> To speed up drawing, always set visible=false for component which you want to hide.



  • Thanks. Works much better now following the simple rules:

    1. Children provide implizitWidth/implicitHeight to be used by parent
    2. Parent sets sizes using width/height, taking the children's wishes into account

Log in to reply