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 }
       }
    }
}
Другие вопросы по тегам