QML: проблемы с перекрытием мышиной области
У меня есть приложение QML и проблемы с MouseAreas.
В небольшом тестовом приложении есть красный прямоугольник, и когда мышь входит в этот прямоугольник, ниже появляется серое меню (созданное с помощью Loader).
Это серое меню должно быть открыто, когда мышь находится над красным прямоугольником или меню. Для этого у меня есть 2 MouseAreas, 1 над красным прямоугольником и 1 над меню. Оба являются "hoverEnabled" и с "enter" и "exit", я управляю "hoverDialog" и "hoverTopZone".
Когда оба имеют значение false, это означает, что мышь отсутствует, поэтому я закрываю меню (используя сигнал, загрузчик становится неактивным).
Таймер необходим, так как при переходе от mouseAreaTopZone к mouseAreaDialog есть только один момент, когда hoverDialog и hoverTopZone имеют значение false. Исправлено с таймером.
В середине меню есть зеленый прямоугольник, и (только), когда мышь находится там, желтый прямоугольник должен быть виден.
Есть моя проблема. У меня есть MouseArea внутри зеленого прямоугольника, но желтый прямоугольник не отображается при необходимости.
Если я переместлю 'rectGreen' ниже 'mouseAreaTopZone' и 'mouseAreaDialog' (то есть в конце файла), я получу желтый прямоугольник, видимый, когда мышь находится над зеленым прямоугольником, так как его область мыши тогда является "самой верхней"
НО в этом случае диалоговое окно меню закрывается, поскольку, когда мышь входит в MouseArea внутри зеленого прямоугольника, hoverDialog и hoverTopZone имеют значение false...
Я надеюсь, что вы можете понять мою проблему... Вот мой код:
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(); }
}
}
Заранее спасибо, Диего
1 ответ
Спасибо Марк Ch за вашу помощь.
Мне нужно закрыть диалоговое окно при выходе из мыши, поэтому я не могу использовать элемент управления "Всплывающее окно"...
Я решил проблему. Используя только одну переменную, чтобы узнать, находится ли мышь над моим диалогом ('m_iNumHovered'), я добавляю ссылку каждый раз, когда вхожу в область мыши, и уменьшаю ее при выходе. Ключом было добавить / удалить ссылку в MouseArea над зеленым прямоугольником, чтобы сохранить ее "m_iNumHovered = true" (диалоговое окно отображается)
Новый код для 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 }
}
}
}