QML MouseArea學習小結


QML中的MouseArea類型為用戶進行簡單的鼠標操作提供了方便。

MouseArea是一個不可見的Item,通常與可見項目結合使用,以便為該項目提供鼠標處理。通過有效地充當代理,鼠標處理的邏輯可以包含在MouseArea Item中。

MouseArea雖然是一個不可見的Item,但是它有一個“visible”屬性,當該屬性為假時,鼠標區域就對鼠標事件變得透明。

MouseArea使用實例:

main.qml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
 
import  QtQuick  2 . 12
import  QtQuick.Window  2 . 12

Window
{
    id : window
    visible : 
true
    width : 
640
    height : 
480
    title : qsTr(
"Mouse Area" )

    Rectangle
    {
        id : rect
        anchors.left : window.left
        anchors.leftMargin : 
10
        width : 
100 ;
        height : 
100
        color : 
"green"

        MouseArea
        {
            anchors.fill : parent
            onClicked :
            {
                parent.color = 
'red' ;
            }
        }
    }

    Rectangle
    {
        id : roundrect
        anchors.left : rect.right
        anchors.leftMargin : 
10
        width : 
100 ;
        height : 
100
        color : 
"red"
        radius : 
20

        MouseArea
        {
            anchors.fill : parent
            onClicked :
            {
                parent.color = 
'green'
            }
        }
    }
}

常規測試實驗證實,MouseArea有一個矩形的形狀區域,這就會導致一些不是矩形形狀的Item不能有效地獲取實際形狀的鼠標操作區域。如圓角矩形,在圓形按鈕周圍的假想方塊的角落的鼠標操作也會被捕獲,這顯然不符合精准拾取的現實。

進階地,文章“How to create a round mouse area in QML “提供了一種圓形鼠標區域RoundMouseArea:

 

RoundMouseArea.qml 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 
import  QtQuick  2 . 0

Item {
    id: roundMouseArea

    property alias mouseX: mouseArea.mouseX
    property alias mouseY: mouseArea.mouseY

    property bool containsMouse: {
        
var  x1 = width /  2 ;
        
var  y1 = height /  2 ;
        
var  x2 = mouseX;
        
var  y2 = mouseY;
        
var  distanceFromCenter = Math.pow(x1 - x2,  2 ) + Math.pow(y1 - y2,  2 );
        
var  radiusSquared = Math.pow(Math.min(width, height) /  2 2 );
        
var  isWithinOurRadius = distanceFromCenter < radiusSquared;
        
return  isWithinOurRadius;
    }

    readonly property bool pressed: containsMouse && mouseArea.pressed

    signal clicked

    MouseArea {
        id: mouseArea
        anchors.fill: parent
        hoverEnabled: 
true
        acceptedButtons: Qt.LeftButton | Qt.RightButton
        onClicked: 
if  (roundMouseArea.containsMouse) roundMouseArea.clicked()
    }
}

main.qml中使用:

 

main.qml片段 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
RoundMouseArea {
    id : roundMouseArea
    width :  100
    height : 
100
    anchors.centerIn : parent

    onClicked : print(
"clicked" )

    
// Show the boundary of the area and whether or not it's hovered.
    Rectangle     {
        color : roundMouseArea.pressed ? 
"red"  : (roundMouseArea.containsMouse ?  "darkorange"  :  "transparent" )
        border.color : 
"darkorange"
        radius : width / 
2
        anchors.fill : parent
    }
}

我們可以根據需要重寫containsMouse來規定自己的鼠標區域,但是需要計算不同區域的數學知識,需要一定的功底。

再進一步,應該把鼠標區域一般化,可以使用任意的路徑形狀來表示才好。Qt自帶一個例子maskedmousearea,此示例提供了一種使用任何形狀的Mask的方法,它可以根據您的需求進行定制。

先睹為快:

該demo是一個異形窗口,主要展示鼠標在和異形區域交互的使用,如上圖所示,當鼠標移動到白雲或者月亮上時,相應的物體會高亮,當鼠標按下時,物體會有一個放大的動畫效果,鼠標離開時恢復原樣。

class MaskedMouseArea : public QQuickItem

核心主要時判斷鼠標點是否在圖片有效區域內:

 

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
bool  MaskedMouseArea::contains( const  QPointF &point)  const
{
    
if  (!QQuickItem::contains(point) || m_maskImage.isNull())
        
return   false ;

    QPoint p = point.toPoint();

    
if  (p.x() <  0  || p.x() >= m_maskImage.width() ||
            p.y() < 
0  || p.y() >= m_maskImage.height())
        
return   false ;

    qreal r = qBound<
int >( 0 , m_alphaThreshold *  255 255 );
    
//根據alpha值判斷 異形區域
     return  qAlpha(m_maskImage.pixel(p)) > r;
}

 

 qml Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 
Image {
    id : moon
    anchors.centerIn : parent
    scale : moonArea.pressed ?  1 . 1  :  1 . 0
    opacity : moonArea.containsMouse ? 
1 . 0  :  0 . 7
    source : Qt.resolvedUrl(
"images/moon.png" )

    MaskedMouseArea {
        id : moonArea
        anchors.fill : parent
        alphaThreshold : 
0 . 4
        maskSource : moon.source
    }

    Behavior on opacity {
        NumberAnimation {
            duration : 
200
        }
    }
    Behavior on scale {
        NumberAnimation
        {
            duration : 
100
        }
    }
}

gif走起來:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM