源码地址:https://github.com/0312birdzhang/harbour-hitokoto

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();
    }
}