Unsolved 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 } } } }