QT Demo 之 MouseArea

現在任何一個基本的UI應用中都少不了鼠標的交互(選中、點擊、拖動等等),本篇就從Qt中的MouseArea來開始學習QML編程。幸運的是Qt給我們提供了衆多的Demo工程,針對MouseArea就有一個專門的Demo。

打開MouseArea Demo工程

打開Qt之後,可以通過以下步驟打開MouseArea Demo工程:

打開Demo工程

選中過濾出來的第二個Demo,然後就會打開Project界面。

運行MouseArea Demo工程

進入工程後,按Ctrl+R可以運行Demo工程,運行後彈出下圖的一個UI應用。


在左側的紅色方框上單擊,下方會顯示三行文字;右側的藍色的方框可以按住鼠標左鍵進行拖動。

從運行效果來看,我們需要關注的知識點包括以下幾個:

  • 鼠標在指定區域內的進入和退出
  • 鼠標單擊、雙擊以及釋放的判斷
  • 鼠標左鍵、右鍵和中鍵的判斷
  • 鼠標當前位置的獲取
  • 鼠標拖動的處理
  • 文字的顯示

mousearea.qml源碼分析

點擊右側的編輯按鈕,就會顯示項目的文件列表:


文件列表中的mousearea.qml就是我們需要重點關注的內容,如果你問爲什麼不是像VS工程一樣,先從.cpp文件(或是.h文件)開始看起,這裏簡單的講就是我們創建的是一個QML工程,肯定要把關注點放在qml文件上。

另外一點,打開工程描述文件mousearea.qmlproject,我們可以看到這樣的一行:

mainFile: "mousearea.qml"

也告訴我們應該從mousearea.qml作爲入口查看代碼。

Rectangle {
    id: box
    width: 320; height: 480

    Rectangle {...}
    Rectangle {...}

    Text {...}
    Text {...}
    Text {...}
}
代碼的結構和UI呈現一致,包括2個Rectange和3個Text,兩個Rectange分別是紅色和藍色,上面分別有文字Click和Drag,下面的三個Text分別表示操作(Entered、Exited和Pressed),狀態(Cliecked、Released和Double Clicked)以及座標信息。

展開代碼後,我們按照上一節提到的幾點逐個分析。

Entered和Exited的處理

MouseArea已經做了封裝,只需要設置onEntered和onExited事件處理函數即可,在這裏分別是:
            onEntered: info.text = 'Entered'
            onExited: info.text = 'Exited (pressed=' + pressed + ')'

鼠標單擊、雙擊以及釋放的判斷

針對每一種操作,Qt分別封裝了不同的事件響應,分別有:

  • onClicked:單擊
  • onDoubleClicked:雙擊
  • onPressed:按下鼠標
  • onReleased:釋放鼠標
  • onPressAndHold:長按鼠標

在代碼中可以編寫每一種操作的事件響應函數,從而可以完成自己的需求。

鼠標左右鍵的判斷

在onPressed事件處理函數中,可以通過mouse.button的值和Qt內置變量比較來判斷

                if (mouse.button == Qt.LeftButton)
                    buttonID = 'LeftButton'
                else if (mouse.button == Qt.RightButton)
                    buttonID = 'RightButton'
                else if (mouse.button == Qt.MidButton)
                    buttonID = 'MiddleButton'

Text文字的顯示

上面的代碼聲明瞭一個Text,id是info,其它地方可以直接使用info表示該Text。需要在該Text上顯示文字時直接調用info.text = '要顯示的字符串'即可,如上面的MouseArea的onEntered事件處理函數:

onEntered: info.text = 'Entered'
注:當Text中的文字改變時,會觸發onTextChanged事件,此時我們可以把text的內容通過console.log(text)函數輸出到調試窗口。

    Text {
        id: info
        anchors.bottom: btn.top; anchors.horizontalCenter: parent.horizontalCenter; anchors.margins: 20

        onTextChanged: console.log(text)
    }

鼠標位置的獲取

在onPressed事件處理函數中,可以通過mouse.x和mouse.y來獲取在當前控件中x和y的座標,映射到主元素box(即當前Window)的座標可以通過下述方法獲得:

                var posInBox = redSquare.mapToItem(box, mouse.x, mouse.y)
                posInfo.text = + mouse.x + ',' + mouse.y + ' in square'
                        + ' (' + posInBox.x + ',' + posInBox.y + ' in window)'
即把redSquare的x和y映射到box中,獲得一個相對box的一個座標信息。

鼠標拖動效果

        MouseArea {
            anchors.fill: parent

            //! [drag]
            drag.target: blueSquare
            drag.axis: Drag.XAndYAxis
            drag.minimumX: 0
            drag.maximumX: box.width - parent.width
            drag.minimumY: 0
            drag.maximumY: box.height - parent.width
            //! [drag]
        }
blueSquare這個Rectangle中定義的MouseArea詳細描述了鼠標拖動的效果。


第一行通過anchors.fill: parent將元素的尺寸設置爲和父元素一樣//注:此處的parent指的是直接父元素blueSquare,MouseArea也是一個元素,只是沒有顯示效果,此處使用id指定元素的blueSquare亦可;這樣設置的好處就是,點擊blueSquare的任何部分都可以拖動
第二行通過drag.target: blueSquare指定了拖動的目標,即當前的藍色方塊
第三行通過drag.axis: Drag.XAndYAxis指定了拖動的方向,即支持水平和垂直兩個方向的拖動
下面緊接着通過minimumX、maximumXminimumY、maximumY分別指定了拖動的x、y的最小和最大值,即指定了拖動的範圍是(0,0)到(box.width - parent.width,box.height - parent.height)。//注:如果我們指定的範圍是整個window會是怎麼樣呢?答案是,藍色方塊會拖動到window的外面;同理,如果我們希望在左側拖動到window的外面,我們可以設置minimumX的值爲一個負值。

總結

本節學到的知識點:

1. 鼠標的onClicked、onPressed、onReleased等事件的響應處理

2. 鼠標拖動事件的響應處理

3. 當前鼠標信息的獲取

4. Text文本內容的顯示以及事件響應處理


通過上面的代碼,我們可以看到Qt的QML對於事件消息、UI控件、調試輸出等等都做了很高層次的封裝,使得我們可以很方便的進行調用,通過非常簡單的幾行代碼就可完成一個基本的UI界面。

這樣的好處就是我們可以非常方便、快速的構建UI應用程序,簡化和UI控件的的細微控制,從而可以把更多的精力放在具體的業務邏輯處理上;同樣,封裝也就意味着對底層消息事件的管理、UI控件的繪製和刷新等等不瞭解。不過這種取捨,對於開發人員來說就是見仁見智了。

好了,第一篇到這裏就結束了。謝謝閱讀~

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