Russian Qt Forum
Июль 21, 2019, 21:28 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QSqlTableModel и QtreeView древовидная структура отображения.  (Прочитано 1106 раз)
sektor
Чайник
*
Offline Offline

Сообщений: 99


Просмотр профиля
« : Март 09, 2019, 16:46 »

Добрый день форумчане, задача построить древовидную структуру из СУБД вид:

id  name  parent_id
1   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;
}
Записан
sektor
Чайник
*
Offline Offline

Сообщений: 99


Просмотр профиля
« Ответ #1 : Март 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;
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.059 секунд. Запросов: 22.