创建一个QT for Android的传感器应用应用程序(摘自笔者2015年将出的《QT5权威指南》,本文为试读篇)
這個手冊描述了使用Qt Quick面訪的方式在Android和ios設備上開發QtQuick應用程序的方法。我們使用Qt Creator實現一個QtQuick應用程序,這個應用程序基于加速器的值來加速一個SVG(可伸縮矢量圖形)。
設置開發環境:
要想能夠在移動設備上構建和運行一個應用程序,您必須為設備平臺設置開發環境,配置Qt Creator和手機設備之間的連接。
要想部署到Android設備,您必須下載和安裝最新的Android NDK和SDK.更新SDK去獲取為開發所需的API和工具。除此之外,您必須安裝Java的JDK和Apache Ant.當您已經安裝所有的這些工具以后,您必須在Qt Creator中指定它們的位置。如果想了解更多關于這方面的信息,請查看Qt for Android(http://doc.qt.io/qt-5/android-support.html)和連接Android設備(http://doc.qt.io/qtcreator/creator-developing-android.html).
?????? 在IOS設備上開發,您必須安裝Xcode,使用它去配置一個設備。對于這個來說,您需要從蘋果收到一個蘋果開發者的賬號和ISO開發應用認證。如果想了解更多的詳情信息,請查看連接IOS設備(http://doc.qt.io/qtcreator/creator-developing-ios.html)
創建項目:
1 選擇File(文件) > 新建文件或項目 > 應用程序 > QtQuick Application > Choose.
?????? 2 在名稱文本框中,輸入accelbubble.
?????? 3在創建路徑中輸入項目文件存儲的路徑,例如E:\Examples??? ,接著點擊下一步(或在OSX平臺上點擊Continue).
?????? 4在Qt Quick component set下拉選中,選擇Qt Quick Controls 1.1.
?????? 5選擇針對Androidd和iPhone OS的構建套件,然后點擊”下一步”.
?????? 注意:如果在”工具” > “選項” > “構建和運行” > “構建套件”里指定了構建套件設置,那么構建套件將會被顯示出來。筆者的設置如下:
關于Android配置,在配置它之前需要先安裝JDK,下載好了SDK、NDK、Ant工具:
?????? 6在這個dialog窗口后選擇”下一步”,使用默認的設置。
?????? 7查看項目設置,點擊”完成”(或在OS X平臺上點擊完成)
?????? QtCreator生成一個默認的QML文件,在這個文件中可以創建應用程序的主窗口視圖。
創建主窗口視圖:
在應用程序的主窗口正中央顯示一個SVG(主窗口視圖圖形)氣泡的圖片。
在您的項目中使用被Qt Sensors例子使用的BlueBubble.svg,Accel Bubble,您必須從Qt安裝路徑下將它拷貝到項目路徑下(和QML文件相同的子目錄下)。例如:D:\Installed\QT\Examples\Qt-5.4\sensors\accelbubble\content。圖片在Resources中有,您也可以使用其它任何類型的圖片或者一個QML類型的圖片代替(本案例中使用圖片bubble.png代替)。
1 在編輯視圖,鼠標右擊qml.qrc,選擇右鍵菜單中添加現有文件,將項目中的bubble.png資源添加進去。添加后的效果圖如下:
在編輯視圖里面,雙擊main.qml文件,在代碼編輯視圖中打開它。
?????? 2修改ApplicationWindow類型的屬性,指定應用程序的名稱,給定ApplicationWindow的id,設置可見,插入的代碼片段如下:
| import QtQuick 2.2 import QtQuick.Controls 1.1 ? ApplicationWindow { ??? title:qsTr("Accelerate Bubble") ??? id:mainWindow ??? width: 640 ??? height: 480 ??? visible:true ? } |
?????? 3在導航區域,選中Label,按鍵盤上的delete鍵刪除它。
?
?????? 4在“庫” > “QML Type”,選擇Image,并將它拖動到畫布上。并在右側的屬性面板里source部分添加圖片。
?? 注意:您也可以在”庫” > “資源”里看到已經添加進去的資源:
?????? 5選中上圖中的圖片,在屬性面板里,Id域中鍵入bubble,使圖片能夠在其它地方引用它。
?????? 6在代碼編輯區域,給以下的Image添加以下的新的屬性,通過這些屬性來讓將圖片定位在應用程序的正中央。
?????? 7設置圖片位置的x和y的位置,并手動添加圖片寬高屬性。
?????? 6和7步驟后在qml中插入的代碼片段如下:
| Image { ??? id: bubble ??? source: "bubble.png" ??? smooth: true ??? property real centerX: mainWindow.width / 2 ??? property real centerY: mainWindow.height / 2 ??? property real bubbleCenter:bubble.width / 2 ??? x: centerX - bubbleCenter??????? //圖片顯示的x坐標 ??? y: centerY - bubbleCenter??????? //圖片顯示的y坐標 ??? width: 100?????????????????????? //圖片的寬度????? ??? height: 100????????????????????? //圖片的高度 } |
如下是您在做出改變后accelbubble.qml文件的樣子。
| import QtQuick 2.2 import QtQuick.Controls 1.1 ? ApplicationWindow { ??? title: qsTr("Accelerate Bubble") ??? id:mainWindow ??? width: 640 ??? height: 480 ??? visible: true ? ??? Image { ??????? id: bubble ??????? source: "bubble.png" ??????? smooth: true ??????? property real centerX: mainWindow.width / 2 ??????? property real centerY: mainWindow.height / 2 ??????? property real bubbleCenter:bubble.width / 2 ??????? x: centerX - bubbleCenter??????? //圖片顯示的x坐標?? ?????? ?y: centerY - bubbleCenter??????? //圖片顯示的y坐標?? ??????? width: 100?????????????????????? //圖片的寬度????? ??????? height: 100????????????????????? //圖片的高度????? ??? } } |
到此步運行的結果如下:
?????? 既然可視的元素已經在指定位置了,我們可以通過改變加速傳感器的值來改變的bubble的位置
?????? 1添加以下import聲明到main.qml中。
| import QtSensors 5.3 |
?????? 2添加一個含有必要屬性的Accelerometer類型的元素到main.qml中。
| Accelerometer{ ??? id:accel ??? dataRate: 100 ??? active:true } |
?????? 3添加以下的JavaScript方法,實現基于當前Accelerometer的值來計算這個bubble的位置。
| function calcPitch(x,y,z) { ??????? return -(Math.atan(y / Math.sqrt(x * x + z * z)) * 57.2957795); ??? } ??? ??? function calcRoll(x,y,z) ??? { ??????? return -(Math.atan(x / Math.sqrt(y * y + z * z)) * 57.2957795); ??? } |
?????? 4為Accelerometer類型的onReadingChanged信號添加以下的JavaScript代碼,讓bubble隨著Accelerometer的值變化而移動位置。
| Accelerometer{ ??????? id:accel ??????? dataRate: 100 ??????? active:true ??????? ??????? onReadingChanged: { ??????????? var newX = (bubble.x + calcRoll(accel.reading.x, accel.reading.y, accel.reading.z) * 0.1) ??????????? var newY = (bubble.y - calcPitch(accel.reading.x, accel.reading.y, accel.reading.z) * 0.1) ??????????? ??????????? //如果newX和newY都是空的,直接返回 ??????????? if (isNaN(newX) || isNaN(newY)) ??????????????? return; ??????????? ??????????? //如果newX小于0,讓newX = 0 ??????????? if (newX < 0) ??????????????? newX = 0 ??????????? ??????????? if (newX > mainWindow.width - bubble.width) ??????????????? newX = mainWindow.width - bubble.width ??????????? ??????????? if (newY < 18) ??????????????? newY = 18 ??????????? ??????????? if (newY > mainWindow.height - bubble.height) ??????????????? newY = mainWindow.height - bubble.height ???? ??????? ??????????? bubble.x = newX ??????????? bubble.y = newY ??????? } } |
?????? 要想確保bubble的位置總是在屏幕邊界內部。如果Accelerometer返回的不是一個數值(NaN),值將會被忽略,bubble的位置將不產生更新。
?????? 在bubble的x和y屬性上添加SmoothedAnimation行為,讓它移動的時候看起來是平滑的。
| import QtQuick 2.2 import QtQuick.Controls 1.1 import QtSensors 5.3 ? ApplicationWindow { ??? title: qsTr("Accelerate Bubble") ??? id:mainWindow ??? width: 640 ??? height: 480 ??? visible: true ??? ??? function calcPitch(x,y,z) { ??????? return -(Math.atan(y / Math.sqrt(x * x + z * z)) * 57.2957795); ??? } ??? ??? function calcRoll(x,y,z) ??? { ??????? return -(Math.atan(x / Math.sqrt(y * y + z * z)) * 57.2957795); ??? } ??? ??? Image { ??????? id: bubble ??????? source: "bubble.png" ??????? smooth: true ??????? property real centerX: mainWindow.width / 2 ??????? property real centerY: mainWindow.height / 2 ??????? property real bubbleCenter:bubble.width / 2 ??????? x: centerX - bubbleCenter??????? //圖片顯示的x坐標?? ??????? y: centerY - bubbleCenter??????? //圖片顯示的y坐標?? ??????? width: 100?????????????????????? //圖片的寬度????? ??????? height: 100????????????????????? //圖片的高度?? ?????? ? ??????? Behavior on y { ??????????? SmoothedAnimation { ??????????????? easing.type: Easing.Linear ??????????????? duration: 100 ??????????? } ??????? } ??????? ??????? Behavior on x { ??????????? SmoothedAnimation { ??????????????? easing.type: Easing.Linear ??????????????? duration: 100 ??????????? } ??????? } ??? } ??? ??? Accelerometer{ ??????? id:accel ??????? dataRate: 100 ??????? active:true ??????? ??????? onReadingChanged: { ??????????? var newX = (bubble.x + calcRoll(accel.reading.x, accel.reading.y, ??????????????????????????????????????????? accel.reading.z) * 0.1) ??????????? var newY = (bubble.y - calcPitch(accel.reading.x, accel.reading.y, ???????????????????????????????????????????? accel.reading.z) * 0.1) ??????????? ??????????? //如果newX和newY都是空的,直接返回 ??????????? if (isNaN(newX) || isNaN(newY)) ??????????????? return; ??????????? ??????????? //如果newX小于0,讓newX = 0 ??????????? if (newX < 0) ??????????????? newX = 0 ??????????? ??????????? if (newX > mainWindow.width - bubble.width) ??????????????? newX = mainWindow.width - bubble.width ??????????? ??????????? if (newY < 18) ??????????????? newY = 18 ??????????? ??????????? if (newY > mainWindow.height - bubble.height) ??????????????? newY = mainWindow.height - bubble.height ??????? ???? ??????????? bubble.x = newX ??????????? bubble.y = newY ??????? } ??????? ??? } } |
鎖定設備方向:
默認情況下當設備的方向改變的時候,屏幕默認是跟著旋轉的。如果屏幕的旋轉方向固定,那么現實的效果會更加好。
?????? 將Android手機中的旋轉屬性進行固定住。Qt Creator中生成的AndroidManifest.xml中可以指定它。如果想了解更多關于這方面的信息,請查看“編輯Manifest文件”(http://doc.qt.io/qtcreator/creator-deploying-android.html#editing-manifest-files).
?????? 在IOS平臺上,您可以在一個Info.plist文件鎖定設備的方向,這個plist文件在.pro文件中作為QMAKEINFO PLIST參數來指定。
添加依賴信息
添加依賴:
更新accelbubble.pro文件,跟上以下庫依賴信息:
| QT += quick sensors svg xml |
?????? 在IOS平臺上,您必須靜態鏈接上面的庫,通過添加插件的名稱,明確指定插件QTPLUGIN參數的各各值。為ios構建指定一個qmake范圍(在這個qmake里面也包含QMAKE INFO PLIST參數信息)。
| ios { QTPLUGIN += qsvg qsvgicon qtsensors_ios QMAKE_INFO_PLIST = Info.plist } |
?????? 添加完了依賴以后,選擇”構建” > “執行qmake”,將改變應用到項目的Makefile文件中去。
添加資源:
您需要添加Bluebubble.svg圖片文件到要部署到手機設備上的應用程序資源文件夾里去。
選中項目中的qml.qrc文件,右擊這個qrc文件,選擇”添加現有文件”將Bluebubble.svg文件添加進去。
運行應用程序:
應用程序被編譯并且將部署到設備上:
?????? 1啟動Android設備上的USB調試功能,或者啟動ios設備上的開發者模式。
?????? 2將設備連接到開發電腦上。
?????? 如果您正在運行的是Androidv4.2.2,手機上將彈出一個對話框讓您去確定使用允許USB調試模式連接到PC機上。要避免每次連接設備的時候彈出一個對話框,點擊”總是允許電腦”,并選擇OK.
?????? 3在設備上運行應用程序,按Ctrl+R。
示例代碼:
?????? 當您一步步完成之后,main.qml文件看起來應該像下面的樣子:
| import QtQuick 2.2 import QtQuick.Controls 1.1 import QtSensors 5.3 ? ApplicationWindow { ??? title: qsTr("Accelerate Bubble") ??? id:mainWindow ??? width: 640 ??? height: 480 ??? visible: true ? ??? function calcPitch(x,y,z) { ??????? return -(Math.atan(y / Math.sqrt(x * x + z * z)) * 57.2957795); ??? } ? ??? function calcRoll(x,y,z) ??? { ??????? return -(Math.atan(x / Math.sqrt(y * y + z * z)) * 57.2957795); ??? } ? ??? Image { ??????? id: bubble ??????? source: "bubble.png" ??????? smooth: true ??????? property real centerX: mainWindow.width / 2 ??????? property real centerY: mainWindow.height / 2 ??????? property real bubbleCenter:bubble.width / 2 ??????? x: centerX - bubbleCenter??????? //圖片顯示的x坐標 ??????? y: centerY - bubbleCenter??????? //圖片顯示的y坐標 ??????? width: 100?????????????????????? //圖片的寬度 ??????? height: 100????????????????????? //圖片的高度 ? ??????? Behavior on y { ?????????? ?SmoothedAnimation { ??????????????? easing.type: Easing.Linear ??????????????? duration: 100 ??????????? } ??????? } ? ??????? Behavior on x { ??????????? SmoothedAnimation { ??????????????? easing.type: Easing.Linear ??????????????? duration: 100 ?????? ?????} ??????? } ??? } ? ??? Image { ??????? id: blueubble ??????? source: "Bluebubble.svg" //注意要讓svg圖顯示在手機上,要在pro文件中添加Qt += svg ??????? smooth: true ??????? property real centerX: mainWindow.width / 4 ??????? property real centerY: mainWindow.height / 4 ??????? property real blueubbleCenter:blueubble.width / 2 ??????? x: centerX - blueubbleCenter???? //圖片顯示的x坐標 ??????? y: centerY - blueubbleCenter???? //圖片顯示的y坐標 ??????? width: 100?????????????????????? //圖片的寬度 ??????? height: 100????????????????????? //圖片的高度 ??? } ? ??? Accelerometer{ ??????? id:accel ??????? dataRate: 100 ??????? active:true ? ??????? onReadingChanged: { ??????????? var newX = (bubble.x + calcRoll(accel.reading.x, accel.reading.y, ??????????????????????????????????????????? accel.reading.z) * 0.1) ??????????? var newY = (bubble.y - calcPitch(accel.reading.x, accel.reading.y, ???????????????????????????????????????????? accel.reading.z) * 0.1) ? ??????????? //如果newX和newY都是空的,直接返回 ??????????? if (isNaN(newX) || isNaN(newY)) ??????? ????????return; ? ??????????? //如果newX小于0,讓newX = 0 ??????????? if (newX < 0) ??????????????? newX = 0 ? ??????????? if (newX > mainWindow.width - bubble.width) ??????????????? newX = mainWindow.width - bubble.width ? ??????????? if (newY < 18) ?????????? ?????newY = 18 ? ??????????? if (newY > mainWindow.height - bubble.height) ??????????????? newY = mainWindow.height - bubble.height ? ??????????? bubble.x = newX ??????????? bubble.y = newY ??????? } ??? } ? ??? menuBar:MenuBar { ??????? Menu{ ??????????? title:qsTr("File") ??????????? MenuItem{ ??????????????? text:qsTr("&Open") ??????????????? onTriggered: console.log("Open action triggered"); ??????????? } ??????????? MenuItem{ ??????????????? text:qsTr("Exit") ??????????????? onTriggered:Qt.quit(); ??? ????????} ??????? } ??? } } |
上面的例子在華為手機上運行的效果圖如下:
總結
以上是生活随笔為你收集整理的创建一个QT for Android的传感器应用应用程序(摘自笔者2015年将出的《QT5权威指南》,本文为试读篇)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 海南话骂人怎么说1000句(海南话骂人)
- 下一篇: 1000吨砂船油耗多少一公里?