C++ (Qt)#ifndef TREEMODEL_H#define TREEMODEL_H #include <QAbstractItemModel>#include <QModelIndex>#include <QVariant> class TreeItem; class TreeModel : public QAbstractItemModel{ Q_OBJECT public: TreeModel(const QString &table, QObject *parent = 0); ~TreeModel(); QVariant data(const QModelIndex &index, int role) const; Qt::ItemFlags flags(const QModelIndex &index) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; QModelIndex parent(const QModelIndex &index) const; int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; QString primaryFieldName; QString parentFieldName; QString tableName; private: //void setupModelData(); void init(int id = 0, TreeItem *parent = 0); void setupFieldName(const QString &table, const QString primaryFieldName = "ID", const QString parentFieldName = "P_ID"); TreeItem *rootItem;}; #endif-------------------#include <QtGui>#include <QtSql> #include "treeitem.h"#include "treemodel.h" #define DEFAULT_PRIMARY_FIELD_NAME "ID"#define DEFAULT_PARENT_FIELD_NAME "P_ID" TreeModel::TreeModel(const QString &table, QObject *parent) : QAbstractItemModel(parent){ setupFieldName(table); // setupModelData();}//TreeModel::~TreeModel(){ delete rootItem;}//int TreeModel::columnCount(const QModelIndex &parent) const{ if (parent.isValid()) return static_cast<TreeItem*>(parent.internalPointer())->columnCount(); else return rootItem->columnCount();}//QVariant TreeModel::data(const QModelIndex &index, int role) const{ if (!index.isValid()) return QVariant(); if (role != Qt::DisplayRole) return QVariant(); TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); return item->data(index.column());}//Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const{ if (!index.isValid()) return Qt::ItemIsEnabled; return Qt::ItemIsEnabled | Qt::ItemIsSelectable;}//QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int role) const{ if (orientation == Qt::Horizontal && role == Qt::DisplayRole) return rootItem->data(section); return QVariant();}//QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent)const{ TreeItem *parentItem; if (!parent.isValid()) parentItem = rootItem; else parentItem = static_cast<TreeItem*>(parent.internalPointer()); TreeItem *childItem = parentItem->child(row); if (childItem) return createIndex(row, column, childItem); else return QModelIndex();}//QModelIndex TreeModel::parent(const QModelIndex &index) const{ if (!index.isValid()) return QModelIndex(); TreeItem *childItem = static_cast<TreeItem*>(index.internalPointer()); TreeItem *parentItem = childItem->parent(); if (parentItem == rootItem) return QModelIndex(); return createIndex(parentItem->row(), 0, parentItem);}//int TreeModel::rowCount(const QModelIndex &parent) const{ TreeItem *parentItem; if (!parent.isValid()) parentItem = rootItem; else parentItem = static_cast<TreeItem*>(parent.internalPointer()); return parentItem->childCount();}// Это матырства моего мозга//----------------------------------------------------------------------/*void TreeModel::setupModelData(){ QList<QVariant> rootData; rootData << "Field 1"<< "Field 2"<< "Field 3"<< "Field 4"; rootItem = new TreeItem(rootData); init(0, rootItem); }//void init(int id, TreeItem *parent){ QList<TreeItem*> parents; parents << parent; QSqlQuery q; q.exec(QString("SELECT * FROM %1 WHERE %2=%3").arg(tableName).arg(parentFieldName).arg(id)); while ( q.next()) { QList<QVariant> columnData; if (q.record().count()>0) { for (int column=2; column<q.record().count(); column++) { columnData << q.value(column); } } parents.last()->appendChild(new TreeItem(columnData, parents.last())); init(q.value(q.record().indexOf(primaryFieldName)).toInt(), parents); }}*///void TreeModel::setupFieldName(const QString &table, const QString primaryFieldN, const QString parentFieldN ){ tableName.clear(); primaryFieldName.clear(); parentFieldName.clear(); tableName.append(table); primaryFieldName.append(primaryFieldN); parentFieldName.append(parentFieldN); }
C++ (Qt)void CDataBase::GetData(map<int, pair<int, QString> > &nodesData){ if (!database->isOpen()) return ; QSqlQueryModel model; model.setQuery("SELECT * FROM [nodes] ORDER BY node_id");// ВАЖНО: обязательна сортировка по ID - узла, т.к. после будет один линейный проход// и для каждого последующего узла выше в таблице должен существовать родитель for (long i = 0; i < model.rowCount(); i++) nodesData[model.data(model.index(i, 0)).toInt()] = make_pair(model.data(model.index(i, 1)).toInt(), model.data(model.index(i, 2)).toString());}
C++ (Qt)void MainWindow::CreateTreeView (void){ map<int, pair<int, QString> >nodesData; base->GetData(nodesData); treeView = ui->treeWidget; map <int, pair<int, QString> >::iterator iIter; map<int, QTreeWidgetItem* >treeItems; treeView->blockSignals(true); for (iIter = nodesData.begin(); iIter != nodesData.end(); iIter++) { int k = iIter->first; QTreeWidgetItem *item; if (iIter->second.first == 0) // root node { item = new QTreeWidgetItem(treeView); item->setText(0, iIter->second.second); } else { item = new QTreeWidgetItem(treeItems[iIter->second.first]); item->setText(0, iIter->second.second); } item->setData(1, 1, iIter->first); treeItems[k] = item; } treeView->blockSignals(false);}