[Solved] best way to delegate through sqlite data for qml list view
-
Hey,
I am searching for a simple way to get data from sqlite and put it in my list view.
solutions i found so far is to include a model from c++ or use javascript to get the data.
when i use the javascript method i am not sure how i should create a model out of the data i get from sql to pass it to the listview.can anyone help me?
is there maybe a better way to delegate through my data?
all examples i saw so far only take one value from the database or make a string out of several databse items and then put it in as an text property. i have seen no example where many db entrys get inserted into qml. -
Hi,
"This":http://stackoverflow.com/questions/16658360/integrating-sqlite-with-qt-quick might help you
-
Hi SGaist,
thanks for the link. I thought that there is maybe an easier way to do this only with qml but to do it with c++ gives much more possibilities.
I tried the example in the link but got an error.
I am having the problem that RoleNameHash seems not to be defined/included.
@
'RoleNameHash' does not name a type@@#ifndef SQLQUERYMODEL_H
#define SQLQUERYMODEL_H#include <QtSql>
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; }
};#endif // SQLQUERYMODEL_H @
-
Hey,
i solved it. It is really simple. I am wondering why there is not such an simple example anywhere.
main.cpp
@
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlComponent>
#include <QQmlContext>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQueryModel>
#include <QtSql/QSqlQuery>
#include <QDebug>int main(int argc, char *argv[])
{
QApplication app(argc, argv);QQmlApplicationEngine engine; QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName("my.db.sqlite"); if(!db.open()){ qDebug("not open!"); }else{ qDebug("db open!"); } //QSqlQuery drop("drop table List;"); //QSqlQuery create("create table List (sample_text char(200));"); QSqlQuery insert("insert into List values (\"some blaaahahhh!\");"); //drop.exec(); //create.exec(); insert.exec(); QSqlQueryModel *someSqlModel = new QSqlQueryModel(); someSqlModel->setQuery("SELECT * FROM List"); //db.close(); engine.rootContext()->setContextProperty("datamodel", someSqlModel); engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); return app.exec();
}@
in the qml:
@ Rectangle {
ListView {
width: 200; height: 200
model: datamodel
delegate: Row {
Rectangle {
width: 100; height: 40
Text {
anchors.fill: parent
text: display
}
}
}
}
}@ -
Ah, one thing i dont understand is how i can get different rows of the result in my qml delegate. at the moment there is:
@
text: display@this has nothing to do with my data. is this something like a wildcard?
in my opninion it should look like the following but this is not working:@
text: sample_text @ -
If you want to display different things, you have to provide you own roles and use them to access your model
-
I realized it just some seconds ago. thanks anyways.
here is my current implementation:
@#ifndef SQLQUERYMODEL_H
#define SQLQUERYMODEL_H#include <QtSql>
#include <QAbstractItemModel>class SqlQueryModel: public QSqlQueryModel
{
Q_OBJECT
QHash<int,QByteArray> *hash;
public:
explicit SqlQueryModel() : QSqlQueryModel()
{
hash = new QHash<int,QByteArray>;
hash->insert(Qt::UserRole, QByteArray("name"));
hash->insert(Qt::UserRole + 1, QByteArray("title"));
}
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 QHash<int, QByteArray> roleNames() const { return *hash; }
};#endif // SQLQUERYMODEL_H
@ -
One thing you should change: don't use pointers to QHash, there's no need for that. Qt uses implicit sharing for it's containers class as well as heap allocation so you would only rarely need to allocate a QHash on the heap. Also, you don't delete it in any destructor so you are creating a memory leak.
-
It's up to you, you can also use a QScopedPointer so you don't have to delete someSqlModel yourself