I can't use QSqlQueryModel qt 5.3
-
I've a sqlite db and I want to display a query result on a qtquick listview.
I've write this class, overwriting QSqlQueryMode:
@#include <QSqlQueryModel>
#include <QtQuick/QQuickItem>
#include <QSqlError>
#include <QtDebug>
class ListSongModel : public QSqlQueryModel
{
Q_OBJECTprivate:
QStringList _columnNames;
public:const char* COLUMN_NAMES[5] = {
"Filename",
"Title",
"Artist",
"Length",
NULL
};const QString SQL_SELECT=QObject::tr("SELECT Filename, Title, Artist, Length FROM Media ORDER BY Title");
void refresh()
{
setQuery(SQL_SELECT);
if(lastError().type()>0)
qDebug()<<"set query error: "+lastError().text();int i=0; while(COLUMN_NAMES[i]) { setHeaderData(i,Qt::Horizontal, QObject::tr(COLUMN_NAMES[i])); i++; }
}
explicit ListSongModel(QObject *parent = 0) :
QSqlQueryModel(parent)
{
refresh();
}virtual QHash<int, QByteArray> roleNames() const
{
QHash<int, QByteArray> roleNames;
int idx = 0;
while( COLUMN_NAMES[idx]) {
roleNames[Qt::UserRole + idx + 1] = COLUMN_NAMES[idx];
idx++;
}return roleNames;
}
QVariant data(const QModelIndex &index, int role) const { QVariant value = QSqlQueryModel::data(index, role); if(role < Qt::UserRole) { value = QSqlQueryModel::data(index, role); } else { int columnIdx = role - Qt::UserRole - 1; QModelIndex modelIndex = this->index(index.row(), columnIdx); value = QSqlQueryModel::data(modelIndex, Qt::DisplayRole); } return value; }
};
@And then I set the property in the qml context
@ListSongModel songModel;
rootContext()->setContextProperty("ModelSong", &songModel);@The problem is that the qml listview display correctly only the first page, if I scroll down I see only a black list, and then when I scroll up in the list remains only the first element.
What can I do?Thanks
Regards Andrea -
Hi, just guessing but maybe you're running out of roles.
In your roleNames function, the roleNames QHash instance you return are deleted at function exit, so when you scroll perhaps the heap loses sight of that QHash instance and gives you black contents. Try changing that QHash variable to a class member... -
I think that this is not the problem, because I've tried this:
@ virtual QHash<int, QByteArray> roleNames() const
{
QHash<int, QByteArray> *roleNames= new QHash<int, QByteArray>();for (int i=0;i<COLUMN_NAMES.count();i++) { (*roleNames)[Qt::UserRole + i +1] = COLUMN_NAMES.at(i).toLatin1(); } return *roleNames;
}@
And I've the same issue
Regards Andrea -
Hi,
Why are you allocating that hash on the heap ?
From Qt's documenation:
@
QHash<int, QByteArray> AnimalModel::roleNames() const {
QHash<int, QByteArray> roles;
roles[TypeRole] = "type";
roles[SizeRole] = "size";
return roles;
}@ -
Hi,
Because hskoglund wrote that " QHash instance you return are deleted at function exit" so I've tried to allocate it on the heap. (but it was only a test)I can't declare "QHash" as class attribute because roleNames is virtual.
So or I did not understand what you said to do or I do not know what should I do.
EDIT:
now I've understand!
I had instanced my entire object on the heap, and now works@ ListSongModel *songModel = new ListSongModel(this);
rootContext()->setContextProperty("ModelSong", songModel);@Thank you very much!
-
Where did I write that ?
You don't need to, just update the code from the example with your values.
Based on your last example:
@
virtual QHash<int, QByteArray> roleNames() const
{
QHash<int, QByteArray> roles;for (int i=0;i<COLUMN_NAMES.count();i++) { roles[Qt::UserRole + i +1] = COLUMN_NAMES.at(i).toLatin1(); } return roles;
}@