QML:鼠标区域重叠的问题

Posted

技术标签:

【中文标题】QML:鼠标区域重叠的问题【英文标题】:QML: Problems with mousearea overlapping 【发布时间】:2017-07-14 07:55:59 【问题描述】:

我有一个 QML 应用程序和 MouseAreas 的问题。

在一个小型测试应用程序中,有一个红色矩形,当鼠标进入这个矩形时,下面会出现一个灰色菜单(使用加载器创建)。

当鼠标悬停在红色矩形或菜单上时,必须打开此灰色菜单。为此,我有 2 个鼠标区域,1 个在红色矩形上,1 个在菜单上。 两者都是 'hoverEnabled' 和 'enter' 和 'exit' 我控制 'hoverDialog' 和 'hoverTopZone'。

当两者都为假时,表示鼠标不在,所以我关闭了菜单(使用信号,加载器处于非活动状态)。

计时器是必需的,因为当从“mouseAreaTopZone”传递到“mouseAreaDialog”时,“hoverDialog”和“hoverTopZone”都是假的。 用计时器修复。

在菜单中间有一个绿色矩形,并且(仅)当鼠标悬停在那里时,黄色矩形必须可见。

这是我的问题。我在绿色矩形内有一个 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(); 
    

提前致谢, 迭戈

【问题讨论】:

你看过propagateComposedEvents属性了吗? 按钮和弹出窗口是否都必须通过悬停来控制?如果您将要求更改为像普通菜单一样使用工作(只要用户单击并按住,菜单就会保持打开状态,然后当鼠标在菜单外释放时释放),那么您可以使用 Quick 中的 Popup 轻松完成控制 2.0,并将 closePolicy 设置为 Popup.CloseOnReleaseOutside 【参考方案1】:

感谢 Mark Ch 的帮助。

我需要在鼠标退出时关闭对话框,所以我认为我不能使用'Popup'控件...

我解决了这个问题。只使用一个变量来知道鼠标是否在我的对话框上('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 
       
    

【讨论】:

以上是关于QML:鼠标区域重叠的问题的主要内容,如果未能解决你的问题,请参考以下文章

QML:是不是可以更改鼠标区域的长持续时间

QML MouseArea:如何将鼠标事件传播到其他鼠标区域?

Qt QML - 在 QML 中识别超出鼠标区域范围

QML TableView 鼠标区域不会将点击传播到选择模型

如何将鼠标滚轮滚动添加到垂直滚动条或滚动区域?

QML Mac 全屏模式失去鼠标焦点