關於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:垃圾玩意。。。。。。。。。。。。。。。。。。

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