使用QML LocalStorage来存储我们的数据
2023-09-14 09:06:18 时间
在先前的样例中。我们能够“使用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"
这个路径显然是和我们在实际在手机上执行时产生的实际的路径是不同的:
这也说明在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()));
对于本应用来说,我们希望在退出时得到一个事件来保存我们的设置。全部我们有这样一个特殊的处理。
为了可以对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来得到这个事件。
执行我们的应用:
每当我们退出应用。并又一次启动应用后。我们能够发现我们的绿色的方块是在和上次退出时一样的位置。
相关文章
- Android数据存储(一)----SharedPreferences详解
- 数据存储之归档
- 海量数据存储之nosql教程(转)
- mysql 重新整理——存储引擎[三]
- Centos7 tiup搭建tiBD集群、扩容、缩容存储节点、修改监控节点
- 使用Vitamio打造自己的Android万能播放器(4)——本地播放(快捷搜索、数据存储)
- 存储空间降为原来的1/7,TDengine在中移物联网轨迹数据存储中的应用
- k8s组件说明:ETCD存储组件
- 【网址收藏】如何设置node.js存储路径:node缓存、数据目录
- Hbase万亿级存储性能优化总结:配置项、hdfs、zookeeper、jvm参数等
- 86. 有没有设置能够限制 ABAP 数据库表能够存储的最大记录数?
- Atitit 存储与数据库性能调优流程目录1. 数据库出现性能瓶颈,对外表现有几个方面:
- Atitit 存储方法大总结 目录 1. 存储方式分类2 1.1. 按照数据分类为 结构化 半结构化 非结构化2 1.2. 按照内外部可分类 内部存储和外部存储持久化2 1.3. 按照本地远
- Atitit mysql 存储过程捕获所有异常,以及日志记录异常信息
- 在 SAP BTP Kyma Runtime 上使用 Redis 读取和存储数据
- 【华为云技术分享】十分钟从入门到精通(上)—对象存储服务的OBS权限配置
- 【成为架构师课程系列】使用 Cache-Aside 模式将数据存储在缓存中( Using the Cache-Aside pattern to store data in the cache)
- Java存储区域——JVM札记<一个>
- 数据存储(两)--SAX发动机XML记忆(附Demo)
- 阿里云对象存储OSS使用 HTTPS
- y17.第一章 Ceph企业级存储实战进阶 -- ceph crush进阶(十七)
- 35 | 存储器层次结构全景:数据存储的大金字塔长什么样?
- Cassandra二级索引原理——新创建了一张表格,同时将原始表格之中的索引字段作为新索引表的Primary Key,并且存储的值为原始数据的Primary Key,然后再通过pk一级索引找到真正的值
- 将mnist数据集存储到本地文件
- 使用存储过程的优点:
- 大数据Hadoop之——数据采集存储到HDFS实战(Python版本)
- HCIE-Cloud Computing LAB备考第二步:逐题攻破--第一题:FusionCompute--“扩容CNA与对接共享存储”的理论解读和解题详述
- Mysql之数据存储路径迁移
- MySQL基础篇 | 存储引擎、事务、索引、视图、DBA命令、数据库设计三范式
- Kubernetes 应用存储和持久化数据卷 上
- Ceph分布式存储集群环境搭建以及节点扩容流程(三)