在先前的样例中。我们能够“使用SQLite offline storage API来存储应用的设置”。我们也在例程“怎样在QML应用中动态改动ListModel中的数据并存储它为JSON格式”中展示怎样把我们须要的JSON存储到一个本地的文件里。

在这篇文章中,我们将使用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"

这个路径显然是和我们在实际在手机上执行时产生的实际的路径是不同的:


watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvVWJ1bnR1VG91Y2g=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="400" height="300" alt="">



这也说明在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来得到这个事件。


执行我们的应用:

  

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvVWJ1bnR1VG91Y2g=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="200" height="300" alt="">



每当我们退出应用。并又一次启动应用后。我们能够发现我们的绿色的方块是在和上次退出时一样的位置。

整个项目的源代码在:https://github.com/liu-xiao-guo/localstorage

使用QML LocalStorage来存储我们的数据的更多相关文章

  1. localStorage 如何存储JSON数据并读取JSON数据

    localStorage是HTML5提供的再客户端实现本地存储的一种方法,但是localStorage方法只能存储字符串数据,有时候我们需要存储对象到本地比如:JSON:那么,localStorage ...

  2. 用localStorage来存储数据的一些经验

    localStorage: 是一种你不主动清除它,它会一直将存储数据存储在客户端的存储方式,即使你关闭了客户端(浏览器),属于本地持久层储存 sessionStorage: 用于本地存储一个会话(se ...

  3. HTML5 localStorage本地存储

    介绍 localStorage(本地存储)的使用方式.包括对存储对象的添加.修改.删除.事件触发等操作. 目录 1. 介绍 1.1 说明 1.2 特点 1.3 浏览器最小版本支持 1.4 适合场景 2 ...

  4. 初识html5的localStorage本地存储

    一.概述 HTML5 提供了两种在客户端存储数据的新方法: localStorage - 没有时间限制的数据存储 sessionStorage - 针对一个 session 的数据存储 之前,这些都是 ...

  5. 关于HTML5本地缓存技术LocalStorage 本地存储 和 SessionStorage

    如果你想在用户访问的时候记录或者记住他们的行为,你会想到的是什么,cookie 和session.但今天告诉你还有两种或者说是1种吧 那就是html5的 LocalStorage 本地存储和 Sess ...

  6. HTML5 LocalStorage 本地存储

    HTML5 LocalStorage 本地存储 说到本地存储,这玩意真是历尽千辛万苦才走到HTML5这一步,之前的历史大概如下图所示: 最早的Cookies自然是大家都知道,问题主要就是太小,大概也就 ...

  7. (转载)HTML5 LocalStorage 本地存储

    原文地址:http://www.cnblogs.com/xiaowei0705/archive/2011/04/19/2021372.html HTML5 LocalStorage 本地存储 说到本地 ...

  8. Localstorage本地存储兼容函数

    前言HTML5提供了本地存储的API:localstorage对象和sessionStorage对象,实现将数据存储到用户的电脑上.Web存储易于使用.支持大容量(但非无限量)数据同时存储,同时兼容当 ...

  9. sessionStorage和localStorage中 存储

    转:http://my.oschina.net/crazymus/blog/371757 sessionStorage只在页面打开是起作用, localStorage关闭页面后仍然起作用. 有时候,我 ...

随机推荐

  1. 架构:Introducing Expert Systems and Distributed Architecure

    原文地址:http://www.yourenterprisearchitect.com/2011/10/introducing-service-bus.html.   Expert Systems. ...

  2. Unity3d-Particle System系统的学习(二)

    这节我们继续上节没讲完的Particle参数. 上节我们讲了Emission发射器参数,我们接着往下讲Shape: 可以看到这个子模块的参数是跟形状有关: 1.Shape:发射形状.粒子被约束在这个形 ...

  3. 推荐一款移动端的web UI控件 -- mobiscroll

    用mobiscroll 可实现ios系统自带的选择器控件效果,支持几乎所有的移动平台(iOS, Android, BlackBerry, Windows Phone 8, Amazon Kindle) ...

  4. ios成长之每日一遍(day 6)

    toolBar上的View Switcher BIDAppDelegate.h #import <UIKit/UIKit.h> @class BIDSwitchViewController ...

  5. Android之仿iphone抖动效果

    转自:http://blog.csdn.net/long33long/article/details/7693671 布局文件: <?xml version="1.0" en ...

  6. Android反编译工具的用法

    Android的APK文件时可以反编译的,通过反编译我们就能查看到大体的代码,帮助学习.反编译仅仅提供的是学习的方式,禁止使用该技术进行非法活动. 其实就是两个命令: 1:运行(WIN+R)-> ...

  7. 通过xml文件来设置动画

    @android:anim/accelerate_interpolator: 越来越快 @android:anim/decelerate_interpolator:越来越慢 @android:anim ...

  8. .condarc(conda 配置文件)、换国内源

    原文地址 https://blog.csdn.net/lanchunhui/article/details/71379555 Configuration — Conda documentation . ...

  9. 7.7 服务远程暴露 - 订阅与通知(TODO)

    为了安全:服务启动的ip全部使用10.10.10.10 远程服务的暴露总体步骤: 将ref封装为invoker 将invoker转换为exporter 启动netty 注册服务到zookeeper 订 ...

  10. dbcp、c3p0、jdbc常用连接配置

    dbcp连接数据库配置  比较常见 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSo ...