PDA

View Full Version : Custom model for QTreeView with SQLite data source



emanuel
19th January 2011, 00:53
Hello,

I'm getting strange qDebug behaviour. Here is the code:




// TreeModel.hpp
#ifndef TREEMODEL_HPP
#define TREEMODEL_HPP

#include <QAbstractItemModel>

class TreeModel : public QAbstractItemModel
{
Q_OBJECT

public:
explicit TreeModel(QObject *parent = 0);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &item, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &index) const;

};

#endif // TREEMODEL_HPP





// TreeModel.cpp
#include <QSqlQuery>
#include <QSqlError>
#include <QVector>
#include <QMessageBox>

#include "TreeModel.hpp"

TreeModel::TreeModel(QObject *parent) :
QAbstractItemModel(parent)
{
}

int TreeModel::rowCount(const QModelIndex &parent) const
{
// top level items
if(!parent.isValid())
{
QSqlQuery q1("SELECT id FROM table_a");

// QSQLITE doesn't support size() function
int size = 0;
while(q1.next())
size++;

return size;
}

// children
if(parent.internalId() == 0)
{
QSqlQuery q2;
q2.prepare("SELECT id FROM table_b WHERE table_a_id = :table_a_id");
q2.bindValue(":table_a_id", parent.data().toInt());
q2.exec();

// QSQLITE doesn't support size() function
int size = 0;
while(q2.next())
size++;

return size;
}

return 0;
}

int TreeModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);

return 1;
}


QVariant TreeModel::data(const QModelIndex &item, int role) const
{
if(!item.isValid())
return QVariant();

if(role == Qt::DisplayRole)
{
if(item.internalId() == 0)
{
// top level item...

if(item.column() == 0)
{
QSqlQuery q1("SELECT id FROM table_a ORDER BY id");

// QSQLITE doesn't like seek() function
int r = 0;
while(q1.next())
{
if(r == item.row())
return q1.value(0).toInt();
r++;
}
}
}
else
{
// child...

QSqlQuery q2;
q2.prepare("SELECT id FROM table_b WHERE table_a_id = :table_a_id ORDER BY id");
q2.bindValue(":table_a_id", item.parent().data().toInt());
q2.exec();

// QSQLITE doesn't like seek() function
int r = 0;
while(q2.next())
{
if(r == item.row())
return q2.value(0).toInt();
r++;
}
}
}

return QVariant();
}


QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if(orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0)
return QString("Id");

return QVariant();
}


Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
{
Q_UNUSED(index);

return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}


QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const
{
if(!parent.isValid())
return createIndex(row, column, 0);

return createIndex(row, column, 1);
}


QModelIndex TreeModel::parent(const QModelIndex &index) const
{
if(index.isValid())
{
if(index.internalId() == 0)
return QModelIndex();
else
{
// this line is fine
qDebug("internalId != 0");

// this line is missing...
qDebug("data: %i", index.data().toInt());

/*

return valid QModelIndex...

*/
}
}

return QModelIndex();
}



Line 143 in TreeModel.cpp doesn't print any output. I was working on parent() function and I discovered that something is wrong with index.data(). I've added qDebug() and... surprise! - qDebug() gives no output. What am I missing here?