Resize problem at the core of QML



  • Hi all!

    Pre to this post was "QML SplitView - handleDelegate"

    I managed (by trial and error) to come up with this code:

    import QtQuick 2.6
    import QtQuick.Controls 1.5
    import QtQuick.Layouts 1.3
    
    Item {
        id: mainItem
        anchors.fill: parent
    
        SplitView {
            id: splitMain
            orientation: Qt.Vertical
            anchors.fill: parent
            signal handleChanged
            property real ratio: 0.6
    
            Rectangle {
                id: r1
                width: {
                    if (splitMain.orientation == Qt.Horizontal) {
                        console.log("width: " + splitMain.width)
                        return splitMain.width * splitMain.ratio
                    }
                }
                height: {
                    if (splitMain.orientation == Qt.Vertical) {
                        console.log("height: " + splitMain.height)
                        return splitMain.height * splitMain.ratio
                    }
                }
                Text {
                    text: splitMain.ratio.toFixed(2)
                }
                onWidthChanged: {
                    if ((splitMain.orientation == Qt.Horizontal)
                            && splitMain.resizing)
                        splitMain.handleChanged()
                }
                onHeightChanged: {
                    if ((splitMain.orientation == Qt.Vertical)
                            && splitMain.resizing)
                        splitMain.handleChanged()
                }
            }
            Rectangle {
                id: r2
                Layout.fillWidth: (splitMain.orientation == Qt.Horizontal) ? true : false
                Layout.fillHeight: (splitMain.orientation == Qt.Vertical) ? true : false
            }
            handleDelegate: Rectangle {
                width: (splitMain.orientation == Qt.Horizontal) ? 4 : 0
                height: (splitMain.orientation == Qt.Vertical) ? 4 : 0
                color: "red"
            }
    
            onHandleChanged: {
                ratio = (splitMain.orientation == Qt.Horizontal) ? r1.width / width : r1.height / height
                console.log("handle changed to ratio " + ratio.toFixed(2))
            }
        }
    }
    

    Please try this urself, without touching the splitview handle, and see that all resizes (including the splitview) like you would expect when you resize the main window.

    Now try again, but now fiddle with the splitview first....

    And now try to resize the containing window...

    As you will see, the SplitView aspect is not kept...

    Now, review my code, I think I made everything possible on Window resize, but it won't keep the aspect ratio of the SplitView.

    So:

    • either my splitMain is not informed of parent (size) changes
    • Or there is something really wrong here

    I am sure there are some experts here?

    To be clear:

    I assume that my anchors.fill parent will trigger something I can work with.

    According to QML bindings and so, the resize of the parent should trigger something in my class... But alas... that does not happen.

    When resizing the parent (without touching SplitView handle) is works ok, but after touching the SplitView handle, it does not.

    Apparently my anchors.fill parent does not trigger anything?
    When parent changes, what do I have to do?

    This is probably a BUG too, right?
    When parent changes, the SplitView should be signaled.

    [Edit: Merged the other very short postings into this one -- @Wieland]


  • Lifetime Qt Champion

    Hi,

    This is a community driven forum. If you want to get in the touch with the developers of Qt you should post on the interest mailing list.

    If you think you may have found something, then you should also check the bug report system to see if it's something known.



  • Hi! I've prepared a small example. The main point here is that using the handle breaks the binding to the rectangle's height property, so it must be restored after resizing.

    main.qml

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.0
    
    ApplicationWindow {
        id: window
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        About {
            anchors.fill: parent
        }
    }
    

    About.qml

    import QtQuick 2.7
    import QtQuick.Controls 1.5
    import QtQuick.Layouts 1.3
    
    SplitView {
        id: splitView
        orientation: Qt.Vertical
    
        // set inital ratio
        property real ratio : 0.33
        // usually you'd use data from your backend object for that
        // property real ratio : backend.ratio()
    
        onRatioChanged: {
            // inform backend about changed ratio
            // backend.setRatio(ratio)
        }
    
        onResizingChanged: {
            if (!resizing) {
                // update height
                ratio = topRect.height / splitView.height
                // restore binding
                topRect.height = Qt.binding(function() {return splitView.height * splitView.ratio})
            }
        }
    
        handleDelegate: Rectangle {
            height: 4
            color: "red"
        }
    
        Rectangle {
            id: topRect
            color: "pink"
            // initialize height. note that this is only valid until the handle is used.
            // using the handle breaks that binding
            height: splitView.height * splitView.ratio
        }
    
        Rectangle {
            id: buttomRect
            color: "plum"
            Layout.fillHeight: true
        }
    }
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.