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

Moving Popup when main window resized



  • I have had some complaints that, in my QML application, if a popup is open and the application window size is reduced, the popup just stays in the same place and gets cut off if the window size is reduced beyond a certain point.

    Of course this is just standard QML behaviour, largely arising from the fact that QML favours 'non-floating' windows for popups, dialogs etc. One approach I have resorted to in the past is to implement the popup or dialog as a separate Window. However, looking at some web-based apps that feature a similar sort of non-floating popup as in QML, I note that they tend to move the popup position dynamically if the window size is reduced.

    I got something like this working in a trivial QML test app, but I achieved it by adding a onWidthChanged handler to my Window and 'driving' the x position of the popup from there. This does not translate well to my real application, which is more complex and the popups are not directly visible from the top-level Window.

    My thought was to try to make the logic more reactive and place it in the Popup. I wondered if I could use the Window attached properties somehow. However, I don't understand where it is valid to use, for example, Window.width. I seem to be allowed to reference it in my Popup without error, but it is always zero.

    Anyway, below is my test app, which also shows the behaviour of Window.width. As I say I don't think there is much mileage in this approach so if anyone has any ideas on approaches I could take I would be grateful.

    import QtQuick 2.9
    import QtQuick.Controls 2.2
    import QtQuick.Window 2.2
    
    Window {
        visible: true; width: 640; height: 480
        title: qsTr("Hello World")
    
        MouseArea {
            anchors.fill: parent
            onClicked: {
                // shows correct value
                console.log(Window.width)
    
                pu.x = mouseX
                pu.y = mouseY
                pu.open();
            }
        }
        Popup {
            id: pu
            height: 150
            width: 150
            property var x0
    
            Rectangle {
                width: parent.width
                height: parent.height
                color: "red"
            }
    
            onOpened: {
                console.log("Window.width = ", Window.width) // always 0!
                x0 = x // remember original x
            }
        }
    
        onWidthChanged: {
            if (pu.x + pu.width > width)
                pu.x -= (pu.x + pu.width - width)
            else
                // keep/revert to original x position where possible
                pu.x = pu.x0
        }
    }
    


  • centerIn
    Covers centering in Item and Window.



  • @fcarney Thanks - that looked promising but I am stuck on 5.9.6 for the moment unfortunately and that does not have Overlay.



  • However, I can use ApplicationWindow.overlay and it is showing the correct width in the Popup now. Thank you @fcarney - this might be enough to get me going now.



  • @Bob64 said in Moving Popup when main window resized:

    but I am stuck on 5.9.6 for the moment unfortunately and that does not have Overlay

    Ahhh! Cruel world!

    Actually just make an empty Item that has the same width and height of parent window. Then center to that Item. I don't think it will let you center in a Window for some reason. Probably because its not an item. Also, anchors.fill wont work on that empty Item either. Annoying.



  • @Bob64 said in Moving Popup when main window resized:

    I can use ApplicationWindow.overlay and it is showing the correct width in the Popup now

    Ooh! I didn't know about that. Can you fill an Item to that overlay too? That is very useful for other things.



  • @fcarney actually, I am not too bothered about anchors and centering as the popups are initially shown in positions based on user mouse clicks, etc. The initial stumbling block for me was just getting hold of the top-level window size and being notified of changes. Now that I can do that, I can think about the details of how I need to react to the changes.


Log in to reply