【Lesson4】跟我写一个“一言”
-
API地址: http://hitokoto.cn/api
一言
通过摇晃手机或吹一吹话筒来改变一言,也就是随机切换一言
为了方便,我们这里只讲晃一晃
Let's begin
1.新建项目
要上架旗鱼商店,必须是harbor-xxx 名称的。所以在创建项目的时候就写好,一劳永逸。如这里我叫harbour-hitokoto
2.添加传感器
打开rpm/harbour-hitokoto.spec文件,在BuildRequires上面添加下面
Requires: qt5-qtdeclarative-import-sensors Requires: qt5-qtsensors-plugin-gestures-shake Requires: qt5-qtsensors-plugin-gestures-sensor
添加完之后的部分配置是这样的
Source0: %{name}-%{version}.tar.bz2 Source100: harbour-hitokoto.yaml Requires: sailfishsilica-qt5 >= 0.10.9 Requires: qt5-qtdeclarative-import-sensors Requires: qt5-qtsensors-plugin-gestures-shake Requires: qt5-qtsensors-plugin-gestures-sensor BuildRequires: pkgconfig(sailfishapp) >= 1.0.2 BuildRequires: pkgconfig(Qt5Core) BuildRequires: pkgconfig(Qt5Qml) BuildRequires: pkgconfig(Qt5Quick) BuildRequires: desktop-file-utils %description
3.调用摇动传感器
在qml/harbor-hitokoto.qml中导入
import QtSensors 5.0
,然后就可以用SensorGesture
了SensorGesture { id:gestureid gestures : ["QtSensors.shake"] enabled: true onDetected:{ //检测到晃动,干一些事 } }
我们新建一个main.js,来进行网络请求等。
main.js内容如下:.pragma library var api = "https://sslapi.hitokoto.cn/?encode=json"; var signalcenter; function sendWebRequest(url, callback, method, postdata) { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { switch(xmlhttp.readyState) { case xmlhttp.OPENED:signalcenter.loadStarted();break; case xmlhttp.HEADERS_RECEIVED:if (xmlhttp.status != 200)signalcenter.loadFailed(qsTr("error connection:")+xmlhttp.status+" "+xmlhttp.statusText);break; case xmlhttp.DONE:if (xmlhttp.status == 200) { try { callback(xmlhttp.responseText); signalcenter.loadFinished(); } catch(e) { console.log(e) signalcenter.loadFailed(qsTr("loading erro...")); } } else { signalcenter.loadFailed(""); } break; } } if(method==="GET") { xmlhttp.open("GET",url); xmlhttp.send(); } if(method==="POST") { xmlhttp.open("POST",url); xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlhttp.setRequestHeader("Content-Length", postdata.length); xmlhttp.send(postdata); } } function gethitokoto(){ sendWebRequest(api, loadResult, "GET",""); } var app; function loadResult(oritxt){ var obj = JSON.parse(oritxt); //console.log(oritxt) app.hitokoto = obj.hitokoto; app.author = obj.creator; app.source = obj.from; app.catname = obj.type; }
创建一个SignalCenter.qml,内容如下:
import QtQuick 2.0 import Sailfish.Silica 1.0 QtObject{ id:signalcenter; signal loadStarted; signal loadFinished; signal loadFailed(string errorstring); }
4.要开始装逼了(笑
在qml/harbor-hitokoto.qml中导入main.js
import main.js as Main
然后...
emmmmmmmm....
我还是直接贴代码吧
import QtQuick 2.0 import Sailfish.Silica 1.0 import QtSensors 5.0 import "./main.js" as JS ApplicationWindow{ id: window property string hitokoto; property string source property string author property string catname property bool loading: false cover: Qt.resolvedUrl("cover/CoverPage.qml") allowedOrientations: Orientation.Portrait _defaultPageOrientations: Orientation.Portrait BusyIndicator { id: busyIndicator anchors.centerIn: parent running: loading size: BusyIndicatorSize.Large } Connections{ target: signalcenter; onLoadStarted:{ window.loading=true; } onLoadFinished:{ window.loading=false; } onLoadFailed:{ window.loading=false; detectedText.text = errorstring; } } Signalcenter{ id:signalcenter } SensorGesture { id:gestureid gestures : ["QtSensors.shake"] enabled: true onDetected:{ JS.gethitokoto() } } SilicaFlickable{ anchors.fill: parent contentHeight: detectedText.height + contentExt.height + Theme.paddingMedium Label{ id:detectedText anchors{ left:parent.left right:parent.right margins: Theme.paddingMedium } y:window.height / 2 - detectedText.height /2 width: parent.width wrapMode: Text.WordWrap font.pixelSize: Theme.fontSizeLarge color: Theme.highlightColor opacity:0.7 font.bold: true horizontalAlignment: Text.AlignLeft truncationMode: TruncationMode.Elide text: getRandomIcon()+ ": "+hitokoto MouseArea{ anchors.fill: parent onPressAndHold: { Clipboard.text = hitokoto; } } } Label{ id:contentExt text:"——"+(source?(source+","):"") width:parent.width * 0.7 wrapMode: Text.WordWrap font.pixelSize:Theme.fontSizeSmall horizontalAlignment: Text.AlignRight anchors{ top:detectedText.bottom right:parent.right margins: Theme.paddingMedium } } } Component.onCompleted: { JS.signalcenter = signalcenter JS.app = window JS.gethitokoto(); } }