QML: Problems with mousearea overlapping



  • Hi,

    I have a QML application and problems with MouseAreas.

    In a small test app, there is a red rectangle and when mouse enters this rect, a grey menu appears below (created with a Loader).

    This grey menu must be open while mouse is over the red rectangle or the menu. For this purpose, I have 2 MouseAreas, 1 over the red rect and 1 over the menu. Both are 'hoverEnabled' and with 'enter' and 'exit' I control 'hoverDialog' and 'hoverTopZone'.

    When both are false, it means that the mouse is out, so I close the menu (using a signal, the Loader gets inactive).

    The timer is required since when passing from 'mouseAreaTopZone' to 'mouseAreaDialog' there is just a moment with 'hoverDialog' and 'hoverTopZone' are both false. Fixed with the timer.

    In the middle of the menu there is a green rect, and (only) when mouse is over there, a yellow rect must be visible.

    There is my problem. I have a MouseArea inside the green rect, but the yellow rect is not visible when required.

    If I move 'rectGreen' below 'mouseAreaTopZone' and 'mouseAreaDialog' (that is, at the end of the file) I get the yellow rect visible when the mouse is over green rect, since its mouse area is then 'topmost'

    BUT in this case, the menu dialog is closed, since when the mouse enters the MouseArea inside green rect, hoverDialog and hoverTopZone are false...

    I hope U can understand my problem... Here is my code:

    Test.qml

    import QtQuick 2.5
    import QtQuick.Controls 1.3
    import QtQuick.Window 2.0
    
    Item {
        width: 800
        height: 800
    
        Rectangle{
            id: rect
            anchors { top: parent.top; topMargin: 100; horizontalCenter: parent.horizontalCenter }
            height: 50; width: 50
            color: "red"
    
            MouseArea {
                anchors.fill: parent
                hoverEnabled: true
                onEntered: loader_dialog.active = true
            }
        }
    
        Loader {
            id: loader_dialog
            anchors { top: rect.bottom; horizontalCenter: rect.horizontalCenter}
            active: false
            sourceComponent: TestMenu {
                onClose: loader_dialog.active = false;
            }
        }
    }
    

    TestMenu.qml

    import QtQuick 2.0
    
    Rectangle {
        id: id_dialog
    
        signal close()
    
        width: 400
        height: 600
    
        color: "lightgrey"
    
        property bool hoverDialog: false
        property bool hoverTopZone: false
    
        function update() {
            if (!hoverDialog && !hoverTopZone)
                timer.start();
        }
    
        function check() {
            if (!hoverDialog && !hoverTopZone)
            {
                console.log("close");
                id_dialog.close();
            }
        }
    
        Timer {
            id: timer
            interval: 100
            running: false
            repeat: false
            onTriggered: check();
        }
    
        Rectangle {
            id: rectGreen
            width: 200; height: 100
            anchors.centerIn: parent
            color: "green"
    
            Rectangle {
                id: rectYellow
                anchors.centerIn: parent
                width: 50; height: 50
                color: "yellow"
                visible: false
            }
    
            MouseArea {
                anchors.fill: parent
    
                hoverEnabled: true
                onEntered: { rectYellow.visible = true; }
                onExited: { rectYellow.visible = false }
            }
        }
    
        MouseArea {
            id: mouseAreaTopZone
            anchors { bottom: parent.top; horizontalCenter: parent.horizontalCenter}
            width: 50; height: 50
    
            hoverEnabled: true
            onEntered: { hoverTopZone = true; id_dialog.update(); }
            onExited:  { hoverTopZone = false; id_dialog.update(); }
        }
    
        MouseArea {
            id: mouseAreaDialog
            anchors.fill: parent
    
            hoverEnabled: true
            onEntered: { hoverDialog = true; id_dialog.update(); }
            onExited: { hoverDialog = false; id_dialog.update(); }
        }
    }
    

    Thanks in advance, Diego



  • Thanks Mark Ch for your help.

    I need to close the dialog when the mouse exits, so I think I can not use 'Popup' control...

    I solved the problem. Using only one variable to know if the mouse is over my dialog ('m_iNumHovered'), I add a reference every time I enter in a Mouse Area, and I decrease it when I exit. The key was to add/remove a reference in the MouseArea over the green rectangle, to keep it 'm_iNumHovered=true' (dialog visible)

    New code for TestMenu.qml:

    import QtQuick 2.0
    
    Rectangle {
        id: id_dialog
    
        signal close()
    
        width: 400
        height: 600
    
        color: "lightgrey"
    
        property int m_iNumHovered: 0
        onM_iNumHoveredChanged: update();
    
        function update() {
            if (m_iNumHovered == 0)
                timer.start();
        }
    
        function check() {
            if (m_iNumHovered == 0)
                id_dialog.close();
        }
    
        Timer {
            id: timer
            interval: 100
            running: false
            repeat: false
            onTriggered: check();
        }
    
        MouseArea {
            id: mouseAreaTopZone
            anchors { bottom: parent.top; horizontalCenter: parent.horizontalCenter}
            width: 50; height: 50
    
            hoverEnabled: true
            onEntered: m_iNumHovered++;
            onExited: m_iNumHovered--;
        }
    
        MouseArea {
            id: mouseAreaDialog
            anchors.fill: parent
    
            hoverEnabled: true
            onEntered: m_iNumHovered++;
            onExited: m_iNumHovered--;
        }
    
        Rectangle {
            id: rectGreen
            width: 200; height: 100
            anchors.centerIn: parent
            color: "green"
    
            Rectangle {
                id: rectYellow
                anchors.centerIn: parent
                width: 50; height: 50
                color: "yellow"
                visible: false
            }
    
            MouseArea {
                anchors.fill: parent
    
                hoverEnabled: true
                onEntered: { m_iNumHovered++; rectYellow.visible = true; }
                onExited: { m_iNumHovered--; rectYellow.visible = false }
           }
        }
    }
    

Log in to reply
 

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