Создание модели для QTreeView

650
29 декабря 2016, 08:03

Помогите разобраться с принципами Model/View программирования в Qt. Пытаюсь реализовать свой класс, наследующий QAbstractItemModel.
Есть таблица MySQL, имеющая вид:

id  name        parent  
1   Group1      0  
2   Group1.1    1  
3   Group1.2    1  
4   Group2      0  
5   Group2.1    4  
6   Group1.3    1
7   Group3      0  
8   Group3.1    7  
9   Group3.1.1  8
10  Group3.1.2  8

Структура дерева, думаю, понятна. С реализацией методов rowCount(), columnCount(), setHeaderData() я более-менее разобрался. Не могу понять остального (index(), data()). Помогите реализовать вывод этого дерева в QTreeView, пожалуйста.

Answer 1

Для простоты забудем про базу данных. Пусть у нас есть массив соответствующих структур и функции доступа к ним:

struct Record {
    int id;
    QString name;
    int parent_id;
};
const Record records[] = {
    { 1  , "Group1    " , 0 },
    { 2  , "Group1.1  " , 1 },
    { 3  , "Group1.2  " , 1 },
    { 4  , "Group2    " , 0 },
    { 5  , "Group2.1  " , 4 },
    { 6  , "Group1.3  " , 1 },
    { 7  , "Group3    " , 0 },
    { 8  , "Group3.1  " , 7 },
    { 9  , "Group3.1.1" , 8 },
    { 10 , "Group3.1.2" , 8 },
};
QVector<int> childIds( int parent_id )
{
    QVector<int>  ret;
    for( auto& r : records )
        if(r.parent_id == parent_id)
            ret.push_back( r.id );
    return ret;
}
const Record& recordById(int id)
{
    for( auto& r : records )
        if(r.id == id)
            return r;
}

Будем хранить в поле internalId индекса id соответствующей записи. Тогда:

class Model : public QAbstractItemModel
{
    Q_OBJECT
public:
    explicit Model(QObject *parent = 0)
        : QAbstractItemModel(parent)
    {}
    ~Model()
    {}
    QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
    QModelIndex parent(const QModelIndex &child) const;
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    int columnCount(const QModelIndex &parent = QModelIndex()) const;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
protected:
    QModelIndex indexById(int id) const;
};
QModelIndex Model::index(int row, int column, const QModelIndex &parent) const
{
    int parent_id= parent.isValid() ? parent.internalId() : 0;
    return createIndex( row, column, childIds( parent_id ).at(row) );
}
QModelIndex Model::parent(const QModelIndex &child) const
{
    int id=child.internalId();
    int parent_id= recordById(id).parent_id;
    return indexById(parent_id);
}
int Model::rowCount(const QModelIndex &parent) const
{
    int parent_id= parent.isValid() ? parent.internalId() : 0;
    return childIds(parent_id).size();
}
int Model::columnCount(const QModelIndex &parent) const
{
    return 3;
}
QVariant Model::data(const QModelIndex &index, int role) const
{
    if(role == Qt::DisplayRole )
    {
        auto& r=recordById(index.internalId());
        switch(index.column())
        {
            case 0: return r.id;
            case 1: return r.name;
            case 2: return r.parent_id;
        }
    }
    return QVariant();
}
QModelIndex Model::indexById(int id) const
{
    if(id==0)
        return QModelIndex();
    int parent_id=recordById(id).parent_id;
    int row = childIds( parent_id ).indexOf(id);
    return index(row, 0, indexById(parent_id) );
}
READ ALSO
Ошибка подключения COM объекта: C1083: Cannot open type library file

Ошибка подключения COM объекта: C1083: Cannot open type library file

Имеется COM-объект в виде dllПодскажите пожалуйста как правильно подключить его в c++ приложении из-под винды, компилятор msvc++ 14?

517
Потоки. Ожидание выполнения потоков с++

Потоки. Ожидание выполнения потоков с++

Здравствуйте, подскажите пожалуйста, как заставить 1ю и 2ю функцию выполняться одновременно, а третью ждать пока они обе выполняться? Заранее...

493
нужно перенести алгоритм dtw в R с помощью Rccp

нужно перенести алгоритм dtw в R с помощью Rccp

В R есть пакет с dtw алгоритмом но он очень медленный, я решил его заменить на dtw который написан на с++ от сюдаСкажу сразу, я только изучаю програмирование...

510
Code-review программы для работы с заметками

Code-review программы для работы с заметками

ЗдравствуйтеЯ пишу небольшую программку для работы с заметками

487