I am writing a tree model for an app I'm making that takes it's data from an SQLite database. Each item in the db contains the values "id" (unique identifier), "parent" (id of parent, or 0 for toplevel item), and "name" (the user-visible name of the item).
It compiles fine, but the view comes out empty! I have no idea where to begin troubleshooting.
The code to fill in the db, create the model, and attach it to a QTreeView:
db.setDatabaseName(":memory:");
db.open();
query->exec("CREATE TABLE tags (id INTEGER, parent INTEGER, name TEXT)");
query->exec("INSERT INTO tags VALUES (1, 0, 'item 1')");
query->exec("INSERT INTO tags VALUES (2, 1, 'sub 1')");
query->exec("INSERT INTO tags VALUES (3, 2, 'sub sub 1')");
query->exec("INSERT INTO tags VALUES (4, 2, 'sub sub 2')");
query->exec("INSERT INTO tags VALUES (5, 0, 'item 2')");
query->exec("INSERT INTO tags VALUES (6, 5, 'sub 1')");
tagModel = new TagTreeModel(query);
ui->tagTree->setModel(tagModel);
db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(":memory:");
db.open();
QSqlQuery *query = new QSqlQuery(db);
query->exec("CREATE TABLE tags (id INTEGER, parent INTEGER, name TEXT)");
query->exec("INSERT INTO tags VALUES (1, 0, 'item 1')");
query->exec("INSERT INTO tags VALUES (2, 1, 'sub 1')");
query->exec("INSERT INTO tags VALUES (3, 2, 'sub sub 1')");
query->exec("INSERT INTO tags VALUES (4, 2, 'sub sub 2')");
query->exec("INSERT INTO tags VALUES (5, 0, 'item 2')");
query->exec("INSERT INTO tags VALUES (6, 5, 'sub 1')");
tagModel = new TagTreeModel(query);
ui->tagTree->setModel(tagModel);
To copy to clipboard, switch view to plain text mode
The header for the model class:
{
Q_OBJECT
public:
QVariant headerData
(int seaction, Qt
::Orientation orientation,
int role
) const;
private:
};
class TagTreeModel : public QAbstractItemModel
{
Q_OBJECT
public:
TagTreeModel(QSqlQuery *tagDbQuery);
QModelIndex index(int row, int column, const QModelIndex &parent) const;
QModelIndex parent(const QModelIndex &child) const;
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
QVariant headerData(int seaction, Qt::Orientation orientation, int role) const;
private:
QSqlQuery *query;
};
To copy to clipboard, switch view to plain text mode
The implementation of the model:
TagTreeModel
::TagTreeModel(QSqlQuery *tagDbQuery
) :{
query = tagDbQuery;
}
{
qint32 parentId;
if (parent.isValid())
parentId = parent.internalId();
else
parentId = 0;
query->prepare("SELECT id FROM tags WHERE parent=?");
query->addBindValue(parentId);
query->exec();
if (query->seek(row))
return createIndex(row, column, query->value(0).toInt());
}
{
if (!child.isValid())
query->prepare("SELECT parent FROM tags WHERE id=?");
query->addBindValue(child.internalId());
query->exec();
query->next();
qint32 parent = query->value(0).toInt();
if (parent == 0)
query->prepare("SELECT parent FROM tags WHERE id=?");
query->addBindValue(parent);
query->exec();
query->next();
qint32 parentOfParent = query->value(0).toInt();
int row = 0;
query->prepare("SELECT id FROM tags WHERE parent=?");
query->addBindValue(parentOfParent);
query->exec();
for (int i=0; query->next(); i++)
{
if (query->value(0).toInt() == parent)
{
row = i;
break;
}
}
return createIndex(row, 0, parent);
}
int TagTreeModel
::rowCount(const QModelIndex &parent
) const {
qint32 parentId;
if (parent.isValid())
parentId = parent.internalId();
else
parentId = 0;
query->prepare("SELECT id FROM tags WHERE parent=?");
query->addBindValue(parentId);
query->exec();
return query->size();
}
int TagTreeModel
::columnCount(const QModelIndex &parent
) const {
Q_UNUSED(parent);
return 1;
}
{
if (!index.isValid() || role != Qt::DisplayRole)
query->prepare("SELECT name FROM tags WHERE id=?");
query->addBindValue(index.internalId());
query->exec();
query->next();
return query->value(0);
}
Qt
::ItemFlags TagTreeModel
::flags(const QModelIndex &index
) const{
if (!index.isValid())
return Qt::ItemIsEnabled;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QVariant TagTreeModel
::headerData(int section, Qt
::Orientation orientation,
int role
) const {
Q_UNUSED(section);
if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
}
TagTreeModel::TagTreeModel(QSqlQuery *tagDbQuery) :
QAbstractItemModel()
{
query = tagDbQuery;
}
QModelIndex TagTreeModel::index(int row, int column, const QModelIndex &parent) const
{
qint32 parentId;
if (parent.isValid())
parentId = parent.internalId();
else
parentId = 0;
query->prepare("SELECT id FROM tags WHERE parent=?");
query->addBindValue(parentId);
query->exec();
if (query->seek(row))
return createIndex(row, column, query->value(0).toInt());
return QModelIndex();
}
QModelIndex TagTreeModel::parent(const QModelIndex &child) const
{
if (!child.isValid())
return QModelIndex();
query->prepare("SELECT parent FROM tags WHERE id=?");
query->addBindValue(child.internalId());
query->exec();
query->next();
qint32 parent = query->value(0).toInt();
if (parent == 0)
return QModelIndex();
query->prepare("SELECT parent FROM tags WHERE id=?");
query->addBindValue(parent);
query->exec();
query->next();
qint32 parentOfParent = query->value(0).toInt();
int row = 0;
query->prepare("SELECT id FROM tags WHERE parent=?");
query->addBindValue(parentOfParent);
query->exec();
for (int i=0; query->next(); i++)
{
if (query->value(0).toInt() == parent)
{
row = i;
break;
}
}
return createIndex(row, 0, parent);
}
int TagTreeModel::rowCount(const QModelIndex &parent) const
{
qint32 parentId;
if (parent.isValid())
parentId = parent.internalId();
else
parentId = 0;
query->prepare("SELECT id FROM tags WHERE parent=?");
query->addBindValue(parentId);
query->exec();
return query->size();
}
int TagTreeModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return 1;
}
QVariant TagTreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || role != Qt::DisplayRole)
return QVariant();
query->prepare("SELECT name FROM tags WHERE id=?");
query->addBindValue(index.internalId());
query->exec();
query->next();
return query->value(0);
}
Qt::ItemFlags TagTreeModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::ItemIsEnabled;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QVariant TagTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
Q_UNUSED(section);
if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
return QVariant();
return QVariant(QString("Tag"));
}
To copy to clipboard, switch view to plain text mode
Bookmarks