In this article, we will use the LocalStorage provided by QtQuick to store the data we need.
To illustrate the problem, I will first create a template based on " QtQuick App with QML UI (qmake) ". First we change our main.cpp for example the following:
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();
}
When we execute our application, we can see:
Local storage path: "/home/phablet/.local/share/localstorage/QML/OfflineStorage"
This path is obviously different from the actual path we generated when we actually executed on the phone:
This also shows that the implementation on Ubuntu is different from the standard Qt implementation. From the above we can see that the time path of the database is:
phablet@ubuntu-phablet:~/.local/share/localstorage.liu-xiao-guo/Databases$ ls
4ff10001f402923590ceb1d12a0cffc6.ini 4ff10001f402923590ceb1d12a0cffc6.sqlite
In order to allow the application to exit on its own, we added the following statement, for example:
QObject::connect(view.engine(), SIGNAL(quit()), qApp, SLOT(quit()));
such. When using Qt.quit () in our QML code, we can make the application quit. This is different from our general design. We do not normally need to do this.
For this application, we want to get an event to save our settings when we exit. All of us have such a special treatment.
In order to be able to access the SQLite database. We designed the following database.js file, for example:
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)]); } }); }
Here, we can create a database called "CrazyBox" and produce a table called data in it. We can update the data in the table. From this sample, we can see that this method is used to store our JSON data without using C ++ code (refer to the routine " How to dynamically change the data in ListModel in QML application and store it in JSON format " ). This is good news for most developers who are not very familiar with C ++ code.
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();
}
}
}
}
Our Main.qml design is very easy.
We are after the UI is loaded. Initialize the database and read the stored data. Assuming the data already exists, read it. And initialize our Rectangle "crazy".
When the application exits, we store our data. It should be noted here that when we close the application by dragging with our fingers. Our app cannot accept events such as the following:
Component.onDestruction: {
print("it is going to save data");
DB.storeData();
}
We must get this event by selecting the "Quit" button.
Execute our application:
Whenever we exit the application. And after launching the app again. We can find that our green square is in the same position as the last time we exited.
Note: The js file should be added to qml.qrc, otherwise there will be no problem