Qt on Android: Qt Quick 事件處理之捏拉縮放與旋轉

來源:互聯網
上載者:User

標籤:qt   qt on android   多點觸控   捏拉手勢   

    上一篇《Qt on Android: Qt Quick事件處理之滑鼠、鍵盤、定時器》我們介紹了常見的滑鼠、鍵盤、定時器的處理,滑鼠、鍵盤都是電腦上我們最常使用的事件,這節我們來介紹 Android 智能手機上的一個非常重要的手勢:捏拉手勢。捏拉手勢最早在蘋果手機上得到應用,蘋果還曾經嘗試為此操作申請專利,藉以鉗制三星在美國的手機和平板銷售。這些我們且不管它,咱們只說在 Qt Quick 中如何處理捏拉手勢。

    廣而告之:我正在參加 CSDN 博文大賽,請給我的參賽文章《Qt on Android: Qt Quick 事件處理之訊號與槽》投票,謝謝。

    Qt Quick 中的 PinchArea 帶來捏拉手勢,看名字是不是和 MouseArea 類似?木錯,就是醬紫。先來看 PinchArea 都有哪些屬性和訊號,瞭解了這些才能使用它。

PinchArea簡介

    PinchArea 本身是一個不可見的 Item ,通常和一個可見的 Item 配合使用來處理捏拉手勢。比如和一個 Rectangle 一塊使用,或者和 Image 一塊使用實現圖片縮放、旋轉等效果。捏拉手勢識別實際上是通過對若干觸摸事件的處理來實現的。

屬性

    PinchArea 是 Item 的衍生類別,除了繼承自 Item 的屬性外,還有兩個專屬屬性: enabled 和 pinch 。

    enabled 屬性預設值為 true ,如果你設定為 false ,那麼 PinchArea 就嘛事兒不幹,捏拉地區對滑鼠、觸摸事件就變透明了。

    pinch 屬性知名與捏拉手勢的詳情,它是一個組合屬性,包括 target 、 active 、 minimumScale 、 maximumScale 、 minimumRotation 、 maximumRotation 、 dragAxis 、 minimumX 、 maximumX 、 minimumY 、 maximumY 等屬性。

    target 指明捏拉手勢要操作的 Item , active (bool類型)屬性工作表示目標 Item 是否正在被拖動。

    minimumScale / maximumScale 設定最小、最大縮放係數。 minimuxRotation / maximumRotation 設定對小、最大旋轉角度。這四個屬性都是 real 類型。

    dragAxis 設定沿 X 軸(Pinch.XAxis) 、 Y 軸(Pinch.YAxis) 還是 XY (Pinch.XAndYAxis)兩個軸拖動,你也可以禁止拖動,只要給 dragAxis 賦值 Pinch.NoDrag 即可。當 dragAxis 允許拖動時,minimumX / maximumX 設定 X 軸的最小、最大拖動位置, minimumY / maximumY 設定 Y 軸的最小、最大拖動位置。

訊號

    PinchArea 有三個訊號:onPinchStarted() 、 onPinchUpdated() 、 onPinchFinished() 。它們都有一個名為 pinch 的參數,類型是 PinchEvent 。為了有效響應這些訊號,必須瞭解 PinchEvent 類型,我們先介紹它。

    PinchEvent 具有下列屬性:

  • accepted ,在 onPinchStarted() 訊號處理器中設定為 true 表明你要響應 PinchEvent ,Qt 會持續發給你更新事件;設定為 false ,Qt 就不會再發 PinchEvent 事件給你了。
  • angle ,表示最近兩個觸點之間的角度, previousAngle 是上一次事件的角度, rotation 是從捏拉手勢開始到當前事件的總的旋轉角度。
  • scale ,表示最近兩個觸點之間的縮放係數, previousScale 是上一次事件的縮放係數。
  • center ,兩個觸點的中心點, previousCenter 是上一次事件的中心點, startCenter 是事件開始時的中心點。
  • point1 , point2 儲存當前觸點的位置, startPoint1 , startPoint2 儲存第二個觸點按下時兩個觸點的位置。
  • pointCount 儲存到現在為止的觸點總數。

    onPinchStarted() 訊號在第一次識別到捏拉手勢時發出,如果你要處理它,那就要將其設定為 true 。然後就可以通過 pinch 參數來設定要變換的 Item 了。

    當你在 onPinchStarted() 的訊號處理器中接受了 TouchEvent 事件,那麼 Qt 就會不斷的發送新事件給你, onPinchUpdated() 訊號就會不斷的發射,你可以在它的訊號處理器中通過 pinch 參數,擷取你需要的值來更新你的 Item 。

    onPinchFinished() 訊號在使用者手指離開螢幕時觸發。

怎樣使用

    介紹了 PinchArea 和 PinchEvent ,是時候看看怎麼使用它們了。

    要想使用 PinchArea 來變換一個 Item ,有兩個辦法:

  1. 設定 target 屬性,將其指向要變換的 Item ,然後 PinchArea 就會在合適的時候幫你變換它。
  2. 處理 onPinchStarted() / onPinchUpdated() / onPinchFinished() 訊號,在訊號處理器中變換目標 Item 。這種方式更靈活,你甚至可以同時處理多個 Item 。

    選定一種方式後,你可能還要配置 PinchArea.pinch 屬性,給不同的參數設定合理的值,比方說最大可以放大到多少倍。

縮放與旋轉執行個體

    這裡提供一個簡單的使用 PinchArea 的執行個體,我們用 PinchArea 來旋轉和縮放一個矩形。

    項目的建立參考《Qt on Android: Qt Quick 之 Hello World 圖文詳解》,這裡不再贅述。

使用 pinch.target

    我們先用第一種方式,指定 pinch.target 。直接看 main.qml 文檔吧:

import QtQuick 2.0Rectangle {    width: 360;    height: 360;    focus: true;    Rectangle {        width: 100;        height: 100;        color: "blue";        id: transformRect;        anchors.centerIn: parent;    }    PinchArea {        anchors.fill: parent        pinch.maximumScale: 20;        pinch.minimumScale: 0.2;        pinch.minimumRotation: 0;        pinch.maximumRotation: 90;        pinch.target: transformRect;    }}

    代碼很簡單,初始化了最小、最大縮放係數,最小、最大旋轉角度,然後將 pinch.target 指向 id 為 transformRect 的藍色矩形。於是,一切都正常運轉,兩指捏拉之間,縮放與旋轉效果就出來了。

    圖 1 是在 Android 手機上啟動並執行起始效果:


            圖 1 pinchArea 樣本啟動效果

    圖 2 是我兩個指頭捏拉 了幾下後的效果:


            圖 2 pinchArea 縮放與旋轉效果

    使用 pinch.target 這種方式,你什麼都不用關心,甚至不需要弄明白 pinch 屬性到底是什麼含義,就可以得到一個不錯的變換效果, Qt Quick 預設幫你處理所有的事情。

    下面看看使用訊號的方式。

使用訊號

    使用 onPinchStarted() / onPinchUpdated() / onPinchFinished() 要稍微麻煩一些,你必須要瞭解 PinchEvent 每個參數的含義,自己設計變換策略。不過好處是,七十二般變化都由你控制。

    直接看新的 main.qml 文檔:

import QtQuick 2.0Rectangle {    width: 360;    height: 360;    focus: true;    Rectangle {        width: 100;        height: 100;        color: "blue";        id: transformRect;        anchors.centerIn: parent;    }    PinchArea {        anchors.fill: parent        pinch.maximumScale: 20;        pinch.minimumScale: 0.2;        pinch.minimumRotation: 0;        pinch.maximumRotation: 90;        onPinchStarted: {            pinch.accepted = true;        }        onPinchUpdated: {            transformRect.scale *= pinch.scale;            transformRect.rotation += pinch.rotation;        }        onPinchFinished: {            transformRect.scale *= pinch.scale;            transformRect.rotation += pinch.rotation;        }    }}

    代碼大部分都和 pinch.target 方式一樣,只是去掉了 "pinch.target: transformRect" 語句,改用訊號處理器。代碼很直接,不再解釋了。


    OK,這篇到此結束。

    回顧一下:

  • Qt on Android:Qt Quick 簡介
  • Qt on Android:QML 語言基礎
  • Qt on Android: Qt Quick 之 Hello World 圖文詳解
  • Qt on Android: Qt Quick 簡單教程
  • Qt on Android: Qt Quick 事件處理之訊號與槽
  • Qt on Android: Qt Quick事件處理之滑鼠、鍵盤、定時器

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.