Название: QSqlTableModel и QtreeView древовидная структура отображения.
Отправлено: sektor от Март 09, 2019, 16:46
Добрый день форумчане, задача построить древовидную структуру из СУБД вид: id name parent_id1 name1 0 2 name1.1 1 3 name2 0 4 name2.1 3 Нашел в интернете класс от наследованный от QAbstractProxyModel при запуске программы отображает только родителей то есть name1, name2. Мучаюсь уже несколько дней, пожалуйста помогите. #ifndef MY_SQLTABLEMODEL_H #define MY_SQLTABLEMODEL_H #include <QObject> #include <QAbstractProxyModel> #include <QSqlQuery>
class my_SqlTableModel : public QAbstractProxyModel { public: my_SqlTableModel(QObject* parent);
// QSqlTableModel interface
void setTable(const QString &tableName);
// QAbstractItemModel interface
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 { return sourceModel()->columnCount(parent); }
QVariant headerData(int section, Qt::Orientation orientation, int role) const { return sourceModel()->headerData(section,orientation,role); } bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role) { return sourceModel()->setHeaderData(section,orientation,value,role); }
QModelIndex mapToSource(const QModelIndex &proxyIndex) const; QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;
bool hasChildren(const QModelIndex &parent) const;
private:
int getParentId(int childId) const; QSqlQuery* getChildren(int parentId) const; };
#endif // MY_SQLTABLEMODEL_H
#include "my_sqltablemodel.h" #include <QDebug> my_SqlTableModel::my_SqlTableModel(QObject* parent):QAbstractProxyModel (parent) {
}
QModelIndex my_SqlTableModel::mapFromSource(const QModelIndex &sourceIndex) const { if(!sourceIndex.isValid()) return QModelIndex();
int id = (sourceIndex.column() == 0) ? sourceIndex.data().toInt() : sourceIndex.sibling(sourceIndex.row(),0).data().toInt();
int row = -1; QSqlQuery* q = getChildren(getParentId(id)); while(q->next()) { row++; if(q->value(0).toInt() == id) break; } delete q; return createIndex(row, sourceIndex.column(), id); }
QModelIndex my_SqlTableModel::mapToSource(const QModelIndex &proxyIndex) const { if(!proxyIndex.isValid()) return QModelIndex();
int id = proxyIndex.internalId();
QSqlQuery q; q.exec("SELECT id FROM \"Аудитория\""); int row = -1; while(q.next()) { row++; //qDebug()<<q.value(0).toInt(); if(q.value(0).toInt() == id) break; } return sourceModel()->index(row, proxyIndex.column()); }
bool my_SqlTableModel::hasChildren(const QModelIndex &parent) const {
QSqlQuery q; q.prepare("SELECT COUNT(*) FROM \"Аудитория\" WHERE parent_id=?"); q.addBindValue(parent.internalId()); q.exec(); q.first(); // qDebug() << q.value(0).toInt(); return q.value(0).toInt() > 0; }
QModelIndex my_SqlTableModel::parent(const QModelIndex &childIndex) const {
int childId = childIndex.internalId(); int parentId = getParentId(childId);
qDebug() << childId; //qDebug() << parentId; if(parentId == 0) return QModelIndex();
int parentRow = -1; QSqlQuery* q = getChildren(getParentId(parentId)); while(q->next()) { parentRow++; if(q->value(0).toInt() == parentId) break; } delete q; return createIndex(parentRow, childIndex.row(), parentId); }
QModelIndex my_SqlTableModel::index(int row, int column, const QModelIndex &parent) const {
if(row < 0 || column < 0) return QModelIndex();
QSqlQuery* q = getChildren(parent.internalId()); q->seek(row); int id = q->value(0).toInt(); delete q; return createIndex(row, column, id); }
int my_SqlTableModel::rowCount(const QModelIndex &parent) const {
QSqlQuery* q = getChildren(parent.internalId());
//use last() and at() since SQLite does not support query size calls q->last(); int size = q->at() + 1; delete q; return size; }
int my_SqlTableModel::getParentId(int childId) const { QSqlQuery q; //qDebug()<<childId; q.prepare("SELECT parent_id FROM \"Аудитория\" WHERE id=?"); q.addBindValue(childId); q.exec(); q.first(); //qDebug() << q.value(0).toInt(); return q.value(0).toInt(); }
QSqlQuery* my_SqlTableModel::getChildren(int parentId) const { QSqlQuery* q = new QSqlQuery; //qDebug() << parentId; q->prepare("SELECT id FROM \"Аудитория\" WHERE parent_id=?"); q->addBindValue(parentId); q->exec(); //qDebug() << q->value(0).toInt(); return q; }
Название: Re: QSqlTableModel и QtreeView древовидная структура отображения.
Отправлено: sektor от Март 11, 2019, 13:52
Спасибо за помощь Qt::ItemFlags sqlTreeTableModel::flags(const QModelIndex &index) const { //QSqlTableModel doesn't allow children so use these flags if(index.isValid()) return Qt::ItemIsEnabled | Qt::ItemIsSelectable; else return 0;
|