Qt on Android: Qt Quick事件處理之滑鼠、鍵盤、定時器

來源:互聯網
上載者:User

標籤:qt   qt on android   qt quick   qml   

    在《Qt on Android: Qt Quick 事件處理之訊號與槽》中介紹了 QML 中如何使用內建類型的訊號以及如何自訂訊號,這次我們來看看如何處理滑鼠、鍵盤、定時器等事件。這些時間在處理時,通常是通過訊號來完成的。

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

滑鼠事件處理

    案頭開發的話,難免要處理滑鼠事件……

變色矩形樣本

    看一個簡單的處理滑鼠事件的例子,先看代碼(handle_mouse.qml):

import QtQuick 2.0import QtQuick.Controls 1.1Rectangle {    width: 320;    height: 240;        MouseArea {        anchors.fill: parent;        acceptedButtons: Qt.LeftButton | Qt.RightButton;        onClicked: {            if(mouse.button == Qt.RightButton){                Qt.quit();            }            else if(mouse.button == Qt.LeftButton){                color = Qt.rgba((mouse.x % 255) / 255.0 , (mouse.y % 255) / 255.0, 0.6, 1.0);            }        }        onDoubleClicked: {            color = "gray";        }    }}

    使用 "qmlscene handle_mouse.qml" 命令,可以看到運行效果。上面的代碼僅僅是繪製一個矩形,當滑鼠左鍵按下時改變矩形地區的顏色,滑鼠右鍵按下時退出應用。圖 1 是剛運行時的效果:


            圖1 handle_mouse.qml 初始運行效果

    圖 2 是點擊滑鼠左鍵後的效果:


             圖 2 滑鼠左鍵點擊後的效果

    如果你點一下滑鼠右鍵,程式會退出。

    樣本簡陋,但足以說明如何處理滑鼠事件,下面咱們慢慢來看。

MouseArea

    MouseArea 對象可以附加到一個 item 上供 item 處理滑鼠事件,它本身是一個不可見的 item 。在其內部,可以直接引用它所附著的對象的屬性和方法。你可以將 MouseArea 理解為它所附著的 item 的代理。

    MouseArea 有很多屬性, enabled 用來控制是否處理滑鼠事件,預設值是 true ,如果你設定為 false ,那麼它所代理的 item 就會無視滑鼠事件。 acceptedButtons 屬性設定接收拿些個滑鼠按鍵產生的事件(左鍵、右鍵、中鍵),範例程式碼 "acceptedButtons: Qt.LeftButton | Qt.RightButton;" 表示處理滑鼠左鍵和右鍵。 

    作為一個 item , MouseArea 也擁有 anchors 屬性,你可以使用它來描述有效滑鼠地區。範例程式碼 "anchors.fill: parent;" 表示整個矩形地區都接受滑鼠事件。

    MouseArea 還有很多其他屬性,如 hoverEnabled , pressed 等等,請參考 Qt 協助文檔。

    範例程式碼中,在 MouseArea 對象內使用了 onClicked 和 onDoubleClicked 兩個訊號處理器,他們對應 MouseArea 的 onClicked 和 onDoubleClicked 訊號, MouseArea 還有很多其他的訊號,如 onPressed / onReleased / onEntered / onExited / onPressAndHold 等等,從名字上就可以看到這些訊號的含義。

    onClicked 訊號的參數是 MouseEvent 類型,名為 mouse ,所以你可以在訊號處理器中直接使用 mouse 來查詢滑鼠事件的詳情。比如哪個 button 按下,正如範例程式碼中看到的那樣, MouseEvent 的 button 屬性儲存了被按下的滑鼠按鍵標記, x , y 屬性儲存滑鼠指標位置。還有一個比較重要的屬性 accepted ,如果你處理滑鼠事件後不想這個事件再往下傳遞,就置其值為 true 。

    onDoubleClicked 訊號代表雙擊事件,其參數也是 MouseEvent 類型,樣本中雙擊滑鼠,矩形顏色變為灰色。

    簡單的滑鼠事件處理就這些內容,根據你應用的需要,可能你還會處理 onPressed / onReleased / onEntered 等等訊號,請參考 Qt 協助。

鍵盤事件處理

    手機上你可能較少處理鍵盤事件(有一個例外,BACK 按鍵),但是電腦上你免不了要響應鍵盤。 

會動的文本執行個體

    先看範例程式碼,handle_key.qml :

import QtQuick 2.0import QtQuick.Controls 1.1Rectangle {    width: 320;    height: 480;    color: "gray";        focus: true;    Keys.enabled: true;    Keys.onEscapePressed: {        Qt.quit();    }    Keys.forwardTo: [moveText, likeQt];        Text {        id: moveText;        x: 20;        y: 20;        width: 200;        height: 30;        text: "Moving Text";        color: "blue";        //focus: true;        font { bold: true; pixelSize: 24;}        Keys.enabled: true;        Keys.onPressed: {            switch(event.key){            case Qt.Key_Left:                x -= 10;                break;            case Qt.Key_Right:                x += 10;                break;            case Qt.Key_Down:                y += 10;                break;            case Qt.Key_Up:                y -= 10;                break;            default:                return;            }            event.accepted = true;        }    }        CheckBox {        id: likeQt;        text: "Like Qt Quick";        anchors.left: parent.left;        anchors.leftMargin: 10;        anchors.bottom: parent.bottom;        anchors.bottomMargin: 10;        z: 1;    }}

    這個樣本通過上下左右四個按鍵移動一個文本串,空格鍵選中複選框, Esc 鍵退出應用。圖 3 是初始運行:


            圖 3 handle_key 初始效果

    圖 4 是我按了幾次方向鍵,按了空格鍵後的效果:


            圖 4 移動文本,選中複選框

    下面解釋範例程式碼,介紹如何使用 Keys 對象和訊號處理器處理按鍵事件

Keys 與 訊號處理器

    其實在 《Qt on Android: Qt Quick 事件處理之訊號與槽》、《Qt on Android: Qt Quick 簡單教程》和 《Qt on Android:QML 語言基礎》三篇文章中我們都有提到 Keys 對象,有的樣本中也用到過,這裡呢,我們專門介紹一下,力求使大家對 Keys 及按鍵處理有個較為全面的瞭解。

    Keys 對象是 Qt Quick 提供的,專門供 Item 處理按鍵事件的對象。它定義了很多針對特定按鍵的訊號,比如 onReturnPressed / onEscapePressed / onDownPressed / onDigit0Pressed / onBackPressed 等等;它還定義了更為普通的 onPressed 和 onReleased 訊號,一般地,你可以使用這兩個訊號來處理大部分按鍵(請對照 Qt C++ 中的 keyPressEvent 和 keyReleaseEvent 來理解),它們有一個名字是 event 的 KeyEvent 參數,包含了按鍵的詳細資料。

    KeyEvent 代表一個按鍵事件,如果一個按鍵被處理, event.accepted 應該被設定為 true 以免它被繼續傳遞;要是你不設定它,那它可能會繼續傳遞給其他的 item ,出現一些奇奇怪怪的問題。

    Keys 有三個屬性。

    enabled 屬性控制是否處理按鍵。 

    forwardTo 屬性是清單類型,它表示傳遞按鍵事件給列表內的對象,如果某個對象 accept 了某個按鍵,那位列其後的對象就不會收到該按鍵事件。範例程式碼 "Keys.forwardTo: [moveText, likeQt];" 表明轉寄按鍵給 id 為 moveText 的 Text 對象和 id 為 likeQt 的 CheckBox 對象。 moveText 在前面,如果它消耗掉某個鍵, likeQt 就收不到了。你可以修改 Text 對象的 Keys.onPressed 附加訊號處理器,在 case 列表中添加 Qt.Key_Space 看看效果。

    priority 屬性允許你設定 Keys 附加屬性的優先順序,有兩種,在 Item 之前處理按鍵,這是預設行為,在 Item 之後處理按鍵。你可以對照著 Qt C++ 的 keyPressEvent() 函數來理解,如果你在衍生類別中重載了 keyPressEvent() 方法,那麼你可以在重載方法的一開始調用父類的 keyPressEvent() ,也可以在你處理完感興趣的事件後再調用父類的 keyPressEvent() 。這期間的邏輯關係也很簡單,假如 Keys 先處理按鍵,如它吃掉了某個鍵,它所依附的 Item 對象就收不到這個按鍵了;反之亦然。

    Qt Quick 提供的一些元素本身會處理按鍵,比如樣本中的 CheckBox ,它響應空格鍵來選中或取消選中。而我們不需要給它附加 Keys 對象來再次處理按鍵事件。當然,如果你想改變它的按鍵響應邏輯,可以這麼做,在解釋 priority 屬性時已經提到這點。

    最後還有一點要說明的是,如果你想某個元素處理按鍵,需要把焦點給它,這通過 Item 的 focus 屬性來控制,置 true 即可。

    現在再來解釋下範例程式碼。

    Rectangle 對象的附加訊號處理器 Keys.onEscapePressed 調用 Qt.quit() 退出,小白很,不說了。

    Text 對象實現了 Keys.onPressed 附加訊號處理器,使用 switch-case 語句,分揀 event 參數的 key 屬性。如果是上下左右四個鍵,就變更 Text 的位置,置 accepted 為 true ,聲明這幾個按鍵已名花有主找到歸宿;否則就直接返回,給別人機會處理按鍵。你也看到了,正是因為這樣, CheckBox 才能拿到空格鍵來選中或取消複選框。

    樣本中的 CheckBox 對象定義時,沒有專門處理按鍵,因為 Qt Quick 提供的實現已經處理了按鍵了。

    嗯嗯,貌似內容很少?走著,看定時器去。

定時器

    定時器的作用還要說嗎?好像有點兒囉嗦了呀。定時器麼,就是周期性觸發的一個事件,和平常用的鬧鐘差不多。你可以利用定時器來完成一些周期性的任務,比如檢查和伺服器的串連呆死了沒,比如備份使用者資料……

定時器對象介紹

    在 QML 中, Timer 代表定時器,使用起來也很簡單,響應其 onTriggered() 訊號即可,它也就這麼一個有用的訊號。另外它還有幾個屬性要說明一下, interval 指定定時周期,單位是毫秒,預設值是 1000 毫秒; repeat 設定定時器是周期性觸發還是一次性觸發,預設是一次性的(好像和 QTimer 不一樣噯);running 屬性,設定為 true 定時器就開始工作,設定為 false 就歇菜,預設是 false ; triggeredOnStart 屬性,怎麼說呢, Qt 總是對我們這麼好都有點兒那啥不好意思了,這個屬性是考慮到有些同志的特殊需求,本來定時器啟動後要等待設定的間隔才觸發,如果你設定這個屬性為 true ,那定時器開始執行時立馬先觸發一次,預設值是 false 。

    Timer 還有 start() / stop() / restart() 三個方法可以調用,它們會影響 running 屬性,望文生義吧您。

    現在來看一個簡單的樣本,倒計時。

倒計時程式

    世界盃倒計時按天算,山中一日世上千年,咱們這個樣本用1秒頂它一天,倒數十秒,然後就開香檳慶祝下。

    看代碼(count_down.qml):

import QtQuick 2.0import QtQuick.Controls 1.1Rectangle {    width: 320;    height: 240;    color: "gray";    QtObject{        id: attrs;        property int counter;        Component.onCompleted:{            attrs.counter = 10;        }    }        Text {        id: countShow;        anchors.centerIn: parent;        color: "blue";        font.pixelSize: 40;    }        Timer {        id: countDown;        interval: 1000;        repeat: true;        triggeredOnStart: true;        onTriggered:{            countShow.text = attrs.counter;            attrs.counter -= 1;            if(attrs.counter < 0)            {                countDown.stop();                countShow.text = "Clap Now!";            }        }    }        Button {        id: startButton;        anchors.top: countShow.bottom;        anchors.topMargin: 20;        anchors.horizontalCenter: countShow.horizontalCenter;        text: "Start";        onClicked: {            countDown.start();        }    }}

    我在介面上放了個 Text 對象,它下面放一按鈕。 Rectangle 對象內定義了一個 Timer 對象,預設不啟動。當使用者點擊 "Start" 按鈕時啟動定時器。我還設定了定時器的 triggeredOnStart 屬性哦,周期是 1 秒。

    計數儲存在 QtObject 對象中, id 是 attrs ,在附加訊號處理器 Component.onCompleted 中初始化 counter 屬性的值為 10 。而在 Timer 對象的 onTriggered 訊號處理器中遞減 counter ,當 counter 為 0 時修改 Text 對象的文本為 "Clap Now!" 。

    喏,就這麼簡單。

    來看下效果。圖 5 是初始效果:


            圖 5 倒計時程式初始效果

    圖 6 是計時效果:


            圖 6 計時

    圖 7 是倒計時結束的效果:


            圖 7 倒計時結束

    如果你使用 qmlscene 運行 countdown.qml 文檔,可能會發現它有一個 BUG 哦, "Start" 按鈕第一次點擊可以正常倒數計時,完了下次就不行了……我已經找到問題所在,不過還是留給你解決吧。


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

    

    回顧一下,溫故知新:

  • 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 事件處理之訊號與槽


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.