关于QML中的MouseArea propagateComposedEvents

本文长期固定连接,转发请点赞评论

QML中MouseArea叠加的情况处理方式:

今天在学习QML的过程中,发现一个问题,因为是新手,正在学习,所以难免会碰到各种各样的问题。有些难免很奇葩。先上个代码:

import QtQuick 2.8
import QtQuick.Window 2.2

Window {
    visible: true
    width:root.width
    height: root.height
    title: qsTr("Hello World")//只有加了qsTr才能被国际化的翻译

    Image {
        id: root
        source: "images/background.png"
        width: 960
        height: 640
    }



    Image {
        id: pinwheel
        source: "images/pinwheel.png"
        anchors.centerIn: parent
        Behavior on rotation {
            NumberAnimation{
                duration:250
            }
        }

        MouseArea{
            anchors.fill: parent
            onClicked: {
                 pinwheel.rotation-=360

            }
        }
    }

    Text {
        id: textCenter
        text: qsTr("Hello World")
        anchors.centerIn: parent
    }

    MouseArea{
        anchors.fill: root
        onClicked:{
            pinwheel.rotation+=360
        }
    }

}

这段代码的作用就是显示类似如图的界面:
在这里插入图片描述
这是官网范例中的图片。

问题:

我想实现的功能应该是:
1、点击背景,大风车顺时针转。
2、点击大风车,大风车逆时针转。

但是这个代码Ctrl+R运行的时候,点击大风车并没有逆时针转。说明:点击事件并没有响应大风车这个点击事件。

分析:

什么原因?首先,我是队大风车添加了一个点击事件,然后,我又对root(也就是那个背景图设置了一个点击事件),按照图像显示来说,大风车在背景的上面,理应该响应鼠标事件才对。

猜想:

难道这个东西跟MouseArea所出现在代码中的位置有关?试试,代码如下:

import QtQuick 2.8
import QtQuick.Window 2.2

Window {
    visible: true
    width:root.width
    height: root.height
    title: qsTr("Hello World")//只有加了qsTr才能被国际化的翻译

    Image {
        id: root
        source: "images/background.png"
        width: 960
        height: 640
    }

    MouseArea{
        anchors.fill: root
        onClicked:{
            pinwheel.rotation+=360
        }
    }

    Image {
        id: pinwheel
        source: "images/pinwheel.png"
        anchors.centerIn: parent
        Behavior on rotation {
            NumberAnimation{
                duration:250
            }
        }

        MouseArea{
            anchors.fill: parent
            onClicked: {
                 pinwheel.rotation-=360

            }
        }
    }

    Text {
        id: textCenter
        text: qsTr("Hello World")
        anchors.centerIn: parent
    }


}

对猜想的验证:

运行结果显示,正确的显示了我想要的逆反显示。我也是日了仙人板板了。

再次猜想:

如果这样不直观(毕竟是新手,难免有些东西不了解)那再来一个测试,代码如下:

import QtQuick 2.8
import QtQuick.Window 2.2

Window {
    visible: true
    width:root.width
    height: root.height
    title: qsTr("Hello World")//只有加了qsTr才能被国际化的翻译

    Image {
        id: root
        source: "images/background.png"
        width: 960
        height: 640
    }



    Image {
        id: pinwheel
        source: "images/pinwheel.png"
        anchors.centerIn: parent
        Behavior on rotation {
            NumberAnimation{
                duration:250
            }
        }
    }

    MouseArea{
        anchors.fill: pinwheel
        onClicked: {
             pinwheel.rotation-=360

        }
    }

    MouseArea{
        anchors.fill: root
        onClicked:{
            pinwheel.rotation+=360
        }
    }

    Text {
        id: textCenter
        text: qsTr("Hello World")
        anchors.centerIn: parent
    }


}

再次猜想结果:

运行结果显示,没有逆时针,只有顺时针,哪怕点击了大风车。真实日了仙人板板了。

依样画葫芦:

既然这样(说实话,我觉得很奇怪,这玩意难道不应该跟他的载体有关。结果是叠加在一起的)我们可以大胆的假设一下,这个MouseArea就类似于画矩形图像,一个矩形叠加另外一个矩形,上面的矩形盖住了下面的矩形图像。从视觉上我们看不到下面的矩形,相应的,我们也就相应不了下面的点击事件。

有没有解决办法:

我们知道,Unity是有穿透一说的,那这个是否也有类似的用法了,查了下官方的文档,如下:

propagateComposedEvents : bool
This property holds whether composed mouse events will automatically propagate to other MouseAreas that overlap with this MouseArea but are lower in the visual stacking order. By default, this property is false.
MouseArea contains several composed events: clicked, doubleClicked and pressAndHold. These are composed of basic mouse events, like pressed, and can be propagated differently in comparison to basic events.
If propagateComposedEvents is set to true, then composed events will be automatically propagated to other MouseAreas in the same location in the scene. Each event is propagated to the next enabled MouseArea beneath it in the stacking order, propagating down this visual hierarchy until a MouseArea accepts the event. Unlike pressed events, composed events will not be automatically accepted if no handler is present.
For example, below is a yellow Rectangle that contains a blue Rectangle. The blue rectangle is the top-most item in the hierarchy of the visual stacking order; it will visually rendered above the yellow rectangle. Since the blue rectangle sets propagateComposedEvents to true, and also sets MouseEvent::accepted to false for all received clicked events, any clicked events it receives are propagated to the MouseArea of the yellow rectangle beneath it.

看样子是有的。而且还需要跟mouse.accepted配合使用。那改一下代码。

最终解决方式:

解决方式就是加上两局代码,如图:
在这里插入图片描述
你可以理解成,让上面这个画的矩形区域暂且失效或者说穿透。这样你就能看到下面的内容。所谓的剥开迷雾看世界,大概就是这个道理。

完整代码如下:

import QtQuick 2.8
import QtQuick.Window 2.2

Window {
    visible: true
    width:root.width
    height: root.height
    title: qsTr("Hello World")//只有加了qsTr才能被国际化的翻译

    Image {
        id: root
        source: "images/background.png"
        width: 960
        height: 640
    }

    Image {
        id: pinwheel
        source: "images/pinwheel.png"
        anchors.centerIn: parent
        Behavior on rotation {
            NumberAnimation{
                duration:250
            }
        }
    }

    MouseArea{
        anchors.fill: pinwheel
        onClicked: {
             pinwheel.rotation-=360

        }
    }

    MouseArea{
        anchors.fill: root
        propagateComposedEvents: true
        onClicked:{
            pinwheel.rotation+=360

            mouse.accepted=false
        }
    }

    Text {
        id: textCenter
        text: qsTr("Hello World")
        anchors.centerIn: parent
    }


}

最后总结:

Qt:垃圾玩意。。。。。。。。。。。。。。。。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章