#include <QtGui>#include <QtSql>#include "sqltreemodel.h"void doBranches( int id, const QString& name, int depth ){ int d = depth - 1; int n = qrand() % 10; QSqlQuery query; for ( int i = 0; i < n; i++ ) { QString str = name + QString('1' + i); query.exec( QString("INSERT INTO Object(ParentId, Name) VALUES(%1,'%2')").arg(id).arg(str) ); query.exec( "SELECT last_insert_rowid()" ); if ( query.first() && d ) { int ni = query.value(0).toInt(); doBranches( ni, str, d ); } }}int main(int argc, char *argv[]){ QApplication app(argc, argv); QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName(":memory:"); if (!db.open()) { qFatal("Can't open database"); } QSqlQuery query; query.exec("CREATE TABLE Object (Id integer primary key autoincrement, ParentId integer, Name varchar)"); qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); doBranches( 0, "Item", 3 ); query.exec("CREATE INDEX ParentIdx ON Object(ParentId)"); SqlTreeModel model(db); QTreeView view; view.setModel(&model); view.setWindowTitle(QObject::tr("SQL Tree Model")); view.show(); return app.exec();}
#include <QtGui>#include <QtSql>#include "sqltreemodel.h"// Database access functionsQVariant SqlTreeModel::getData( int id, int column ) const { if ( column != 0 ) return QVariant(); QSqlQuery query(db); query.exec( QString("SELECT Name FROM Object WHERE Id = %1").arg(id) ); if ( !query.next() ) return QVariant(); return query.value(0); }int SqlTreeModel::getParent( int id ) const { QSqlQuery query(db); query.exec( QString("SELECT ParentId FROM Object WHERE Id = %1").arg(id) ); if ( !query.next() ) return -1; return query.value(0).toInt(); }int SqlTreeModel::getChildCount( int parent ) const { QSqlQuery query(db); query.exec( QString("SELECT count(*) FROM Object WHERE ParentId = %1").arg(parent) ); if ( !query.next() ) return 0; int cnt = query.value(0).toInt(); return cnt;}int SqlTreeModel::getChild( int parent, int index ) const { QSqlQuery query(db); if ( !query.exec( QString("SELECT Id FROM Object WHERE ParentId = %1 ORDER BY Id").arg(parent) ) ) return 0; int i = 0; while ( query.next() ) { if ( i == index ) { int id = query.value(0).toInt(); return id; } ++i; } return 0;}int SqlTreeModel::getChildIndex( int parent, int child ) const { QSqlQuery query(db); if ( !query.exec( QString("SELECT Id FROM Object WHERE ParentId = %1 ORDER BY Id").arg(parent) ) ) return -1; int index = 0; while ( query.next() ) { int id = query.value(0).toInt(); if ( id == child ) return index; ++index; } return -1;}//---------------------------------------------------SqlTreeModel::SqlTreeModel(QSqlDatabase database, QObject *parent) : db(database), QAbstractItemModel(parent){}SqlTreeModel::~SqlTreeModel(){}int SqlTreeModel::columnCount(const QModelIndex &parent) const{ return 1; }QVariant SqlTreeModel::data(const QModelIndex &index, int role) const{ if (!index.isValid()) return QVariant(); if (role != Qt::DisplayRole) return QVariant(); return getData( index.internalId(), index.column() );}Qt::ItemFlags SqlTreeModel::flags(const QModelIndex &index) const{ if (!index.isValid()) return 0; return Qt::ItemIsEnabled | Qt::ItemIsSelectable;}QVariant SqlTreeModel::headerData(int section, Qt::Orientation orientation, int role) const{ if (orientation == Qt::Horizontal && role == Qt::DisplayRole) return QString("Name"); return QVariant();}QModelIndex SqlTreeModel::index(int row, int column, const QModelIndex &parent) const{ if (!hasIndex(row, column, parent)) return QModelIndex(); int parentId; if (!parent.isValid()) parentId = 0; else parentId = parent.internalId(); int childId = getChild(parentId, row); if (childId > 0) return createIndex(row, column, childId); else return QModelIndex();}QModelIndex SqlTreeModel::parent(const QModelIndex &index) const{ if (!index.isValid()) return QModelIndex(); int childId = index.internalId(); int parentId = getParent(childId); if (parentId <= 0) return QModelIndex(); int row = getChildIndex(parentId, childId); return createIndex(row, 0, parentId);}int SqlTreeModel::rowCount(const QModelIndex &parent) const{ if (parent.column() > 0) return 0; int parentId; if (!parent.isValid()) parentId = 0; else parentId = parent.internalId(); return getChildCount(parentId);}
int row = getChildIndex(parentId, childId);return createIndex(row, 0, parentId);
QModelIndex SqlTreeModel::parent(const QModelIndex &index) const{ if (!index.isValid()) return QModelIndex(); int childId = index.internalId(); int parentId = getParent(childId); if (!parentId) return QModelIndex(); int row = getChildIndex(getParent(parentId), parentId); return createIndex(row, 0, parentId );}