使用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下 ,不然会出现找不到问题

发布了206 篇原创文章 · 获赞 18 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/lvmengzou/article/details/105231808