使用QML LocalStorage來存儲我們的數據

在這篇文章中,我們將使用QtQuick所提供的LocalStorage來存儲我們所須要的數據。

 

爲了說明問題,我首先來創建一個基於“QtQuick App with QML UI (qmake)”的模版。首先我們改動我們的main.cpp例如以下:

 

Main.qml

 

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QDebug>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQuickView view;
    qDebug() << "Local storage path: " << view.engine()->offlineStoragePath();
    QObject::connect(view.engine(), SIGNAL(quit()), qApp, SLOT(quit()));

    view.setSource(QUrl(QStringLiteral("qrc:///Main.qml")));
    view.setResizeMode(QQuickView::SizeRootObjectToView);
    view.show();
    return app.exec();
}

 

當我們執行我們的應用時,我們能夠看到:

 

Local storage path:  "/home/phablet/.local/share/localstorage/QML/OfflineStorage"


這個路徑顯然是和我們在實際在手機上執行時產生的實際的路徑是不同的:

 

 

 

這也說明在Ubuntu上的實現和標準的Qt上的實現還是不同的。從上面我們能夠看出數據庫的時間路徑爲:

 

phablet@ubuntu-phablet:~/.local/share/localstorage.liu-xiao-guo/Databases$ ls
4ff10001f402923590ceb1d12a0cffc6.ini  4ff10001f402923590ceb1d12a0cffc6.sqlite

 

 

爲了可以使得應用可以自己退出,我們加入了例如以下的語句:

 

  QObject::connect(view.engine(), SIGNAL(quit()), qApp, SLOT(quit()));

 

這樣。在我們的QML代碼中使用Qt.quit()時能夠讓應用退出。這和我們一般的設計是不同的。我們普通情況下是不須要這樣做的。

 

對於本應用來說,我們希望在退出時得到一個事件來保存我們的設置。全部我們有這樣一個特殊的處理。

 

 

爲了可以對SQLite數據庫訪問。我們設計了例如以下的database.js文件:

 

database.js

 

.import QtQuick.LocalStorage 2.0 as Sql

var db;

function initDatabase() {
    print('initDatabase()')

    db = Sql.LocalStorage.openDatabaseSync("CrazyBox", "1.0", "A box who remembers its position", 100000);
    db.transaction( function(tx) {
        print('... create table')
        tx.executeSql('CREATE TABLE IF NOT EXISTS data(name TEXT, value TEXT)');
    });
}

function readData() {
    print('readData()')

    if(!db) { return; }
    db.transaction( function(tx) {
        print('... read crazy object')
        var result = tx.executeSql('select * from data where name="crazy"');
        if(result.rows.length === 1) {
            print('... update crazy geometry')
            // get the value column
            var value = result.rows[0].value;
            // convert to JS object
            var obj = JSON.parse(value)
            // apply to object
            crazy.x = obj.x;
            crazy.y = obj.y;
        }
    });
}

function storeData() {
    print('storeData()')

    if(!db) { return; }
    db.transaction( function(tx) {
        print('... check if a crazy object exists')
        var result = tx.executeSql('SELECT * from data where name = "crazy"');
        // prepare object to be stored as JSON
        var obj = { x: crazy.x, y: crazy.y };
        if(result.rows.length === 1) {// use update
            print('... crazy exists, update it')
            result = tx.executeSql('UPDATE data set value=? where name="crazy"', [JSON.stringify(obj)]);
        } else { // use insert
            print('... crazy does not exists, create it')
            result = tx.executeSql('INSERT INTO data VALUES (?,?

 

)', ['crazy', JSON.stringify(obj)]); } }); }


這裏,我們能夠創建一個叫做“CrazyBox”的數據庫,並在它裏面生產一個叫做data的表。我們能夠向表裏更新數據。從這個樣例裏,我們能夠看出來,用這種方法來存儲我們的JSON數據而不使用到C++代碼(參考例程“怎樣在QML應用中動態改動ListModel中的數據並存儲它爲JSON格式”)。這對大多數不非常熟悉C++代碼的開發人員來說是一個好消息。

 

 

Main.qml

 

import QtQuick 2.0
import Ubuntu.Components 1.1
import "database.js" as DB

/*!
    \brief MainView with a Label and Button elements.
*/

MainView {
    // objectName for functional testing purposes (autopilot-qt5)
    objectName: "mainView"

    // Note! applicationName needs to match the "name" field of the click manifest
    applicationName: "localstorage.liu-xiao-guo"

    /*
     This property enables the application to change orientation
     when the device is rotated. The default is false.
    */
    //automaticOrientation: true

    // Removes the old toolbar and enables new features of the new header.
    useDeprecatedToolbar: false

    width: units.gu(60)
    height: units.gu(85)

    Page {
        title: i18n.tr("Localstorage")

        Rectangle {
            id: crazy
            objectName: 'crazy'
            width: 200
            height: 200
            x: 50
            y: 50
            color: "#53d769"
            border.color: Qt.lighter(color, 1.1)

            Text {
                anchors.centerIn: parent
                text: Math.round(parent.x) + '/' + Math.round(parent.y)
            }

            MouseArea {
                anchors.fill: parent
                drag.target: parent
            }
        }


        Component.onCompleted: {
            DB.initDatabase();

            print("it is going to read data");
            DB.readData();
        }

        Component.onDestruction: {
            print("it is going to save data");
            DB.storeData();
        }

        Button {
            anchors.bottom: parent.bottom
            anchors.bottomMargin: units.gu(1)
            anchors.horizontalCenter: parent.horizontalCenter
            text: "Close"
            onClicked: {
                Qt.quit();
            }
        }
    }
}


 

我們的Main.qml設計很easy。

 

我們在UI被裝載完後。初始化數據庫,並讀取已經存儲的數據。假設數據已經存在,就讀出來。並初始化我們的Rectangle “crazy”。

在應用退出的時候,我們存儲我們的數據。這裏應該注意的是,當我們用我們的手指拖動關掉應用時。我們的應用接受不到例如以下的事件:

 

        Component.onDestruction: {
            print("it is going to save data");
            DB.storeData();
        }


我們必須通過選擇“Quit”button來得到這個事件。

 

執行我們的應用:

 

  

 

 

每當我們退出應用。並又一次啓動應用後。我們能夠發現我們的綠色的方塊是在和上次退出時一樣的位置。

 

注意:js文件要添加到qml.qrc下 ,不然會出現找不到問題

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章