I’m trying to include a SQLite database with QT Quick but I can’t find any examples. I just want to be able to access items from a database. Does anyone know of any example programs I can play with?
db" QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); db. setDatabaseName(path); db.
Many applications use SQLite as a cache of relevant content from an enterprise RDBMS. This reduces latency, since most queries now occur against the local cache and avoid a network round-trip. It also reduces the load on the network and on the central database server.
SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine. Used in Qt SQL Lite plugin.
The theoretical maximum number of rows in a table is 264 (18446744073709551616 or about 1.8e+19). This limit is unreachable since the maximum database size of 281 terabytes will be reached first.
rebus' answer is a great start, but it me left wondering how to connect to an existing (SQLite) database.
So here's a complete example for Qt 5.x, no prerequisites needed.
Notice that the code avoids the role name hashtable lookup in SqlModel.data() and all superfluous heap allocations.
main.cpp
#include <QtDebug>
#include <QString>
#include <QHash>
#include <QGuiApplication>
#include <QtQml>
#include <QQuickView>
#include <QtSql>
#include <QSqlQueryModel>
QSqlError initDb()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
// Open database file. The driver creates a new file if it doesn't exist yet.
db.setDatabaseName("mylibrary.sqlite");
if (!db.open())
return db.lastError();
QStringList tables = db.tables();
if (tables.contains("books", Qt::CaseInsensitive)) {
// DB has already been populated
return QSqlError();
}
QSqlQuery query;
if (!query.exec(QLatin1String("create table books(title varchar, author varchar)")))
return query.lastError();
if (!query.prepare(QLatin1String("insert into books(title, author) values(?, ?)")))
return query.lastError();
auto addBook = [&] (const QString& title, const QString& author) {
query.addBindValue(title);
query.addBindValue(author);
query.exec();
};
addBook("Mademoiselle de Maupin", "T. Gautier");
addBook("Der Nachsommer", "A. Stifter");
addBook("L'Education sentimentale", "G. Flaubert");
addBook("Voyna i mir", "L. Tolstoy");
addBook("Mysterier", "K. Hamsun");
addBook("The Sound and the Fury", "W. Faulkner");
addBook("Tender is the Night", "F. Scott Fitzgerald");
return QSqlError();
}
class SqlModel : public QSqlQueryModel
{
Q_OBJECT
public:
SqlModel(QObject* parent = 0)
: QSqlQueryModel(parent)
{
roleNamesHash.insert(Qt::UserRole, QByteArray("title"));
roleNamesHash.insert(Qt::UserRole + 1, QByteArray("author"));
}
QVariant data(const QModelIndex& index, int role) const
{
if(role < Qt::UserRole)
return QSqlQueryModel::data(index, role);
QSqlRecord r = record(index.row());
return r.value(role - Qt::UserRole);
}
QHash<int, QByteArray> roleNames() const { return roleNamesHash; }
private:
QHash<int, QByteArray> roleNamesHash;
};
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
auto err = initDb();
if (err.type() != QSqlError::NoError) {
qCritical() << err.text();
return 1;
}
SqlModel sqlModel;
sqlModel.setQuery("SELECT title, author FROM books");
QQuickView view;
QQmlContext *context = view.rootContext();
context->setContextProperty("sqlModel", &sqlModel);
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.setSource(QUrl("qrc:///main.qml"));
view.show();
return app.exec();
}
#include "main.moc"
main.qml
import QtQuick 2.1
Item {
width: 500
height: 300
ListView {
anchors { fill: parent; margins: 20 }
model: sqlModel
delegate: Text {
text: author + ' - ' + title
}
}
}
resources.qrc
<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
</RCC>
minimal-qml-sql-app.pro
CONFIG += c++11
QT += qml \
quick \
sql
SOURCES += main.cpp
OTHER_FILES += main.qml
RESOURCES += resources.qrc
You could take QSqlQueryModel for example, or any other SQL model and add it to the QML context and use it in the ListView for example.
Define the role names that will be used by delegates to access data by role in QtQuick components (data
method is bit naive as there is no kind of error checking):
class SqlQueryModel: public QSqlQueryModel
{
Q_OBJECT
QHash<int,QByteArray> *hash;
public:
explicit SqlQueryModel(QObject * parent) : QSqlQueryModel(parent)
{
hash = new QHash<int,QByteArray>;
hash->insert(Qt::UserRole, QByteArray("someRoleName"));
hash->insert(Qt::UserRole + 1, QByteArray("otherRoleName"));
}
QVariant data(const QModelIndex &index, int role) const
{
if(role < Qt::UserRole) {
return QSqlQueryModel::data(index, role);
}
QSqlRecord r = record(index.row());
return r.value(QString(hash->value(role))).toString();
}
inline RoleNameHash roleNames() const { return *hash; }
};
Create an instance of newly defined model class and add it to the QML context
view = new QQuickView();
QSqlQueryModel *someSqlModel = new SqlQueryModel(this);
someSqlModel->setQuery("SELECT someRoleName, otherRoleName FROM some_table");
QQmlContext *context = view->rootContext();
context->setContextProperty("someSqlModel", someSqlModel);
view->setSource(QUrl("qrc:///MainView.qml"));
view->show();
Bind your model to the ListViews model
property and use previously defined role names to access the data in the delegate.
ListView {
id: someListView
model: someSqlModel
delegate: Text {
anchors.fill: parent
text: someRoleName
}
}
How to use a QSqlQueryModel in QML
QML and QSqlTableModel
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With