Russian Qt Forum
Ноябрь 01, 2024, 02:05 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QTreeView + Model: начало  (Прочитано 12406 раз)
Danila_Bagrofff
Гость
« : Май 22, 2012, 17:13 »

Достаточно много работал с вьюшками других типов, но вот с деревом сталкиваюсь в первый раз.

Подскажите, какой формат модели выбрать для следующей задачи.

Необходимо отобразить в дереве информацию следующего вида: Д - док-т со своим набором атрибутов (атр)
П - папка, куда входит документ - свой набор атрибутов

Примерно должно выглядеть так
Д1/атр1/атр2/атр3/
---П1/атр4/атр5/атр6

Д2/атр1/атр2/атр3
--П1....
--П2...
--П3

Д3...
--П2
--П4

Как нужно подготовить данные, чтобы можно было построить такое дерево? В каком формате хранить?
Как учитывается связь между Д и П?
Какую модель надо использовать для такого решения?
Раньше данные свободно хранил к примеру в формате QList<QStringList> для отображения в таблице. Ну или напрямую с сиквелом.

Сейчас я должен как-то представлять данные для модели и никак не определюсь, как.

Связи хранить отдельно?

Раньше все данные можно было взять в модели в data(). Как быть теперь?)

Помогите стартануть - дальше, уверен, пойдет проще =)

« Последнее редактирование: Май 22, 2012, 17:24 от Danila_Bagrofff » Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #1 : Май 25, 2012, 23:13 »

Цитировать
Д1/атр1/атр2/атр3/
---П1/атр4/атр5/атр6
...
Как нужно подготовить данные, чтобы можно было построить такое дерево? В каком формате хранить?
Очень напоминает XML. Сам сейчас пробую пристроить model/view на список xml-документов. Может, между моделью и xml сделать прослойку SQL?
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
RVZ
Гость
« Ответ #2 : Июнь 03, 2012, 15:28 »

Я наверное присоединюсь к теме со своими проблемами... в общем леплю модель деревянную.
И так во всех ранее рассмотренных примерах данные забивались сначала в какой нибудь класс с QList (Куда засовывались потомки) - удобно! но Подразумевается одинаковое количество столбцов на всех уровнях (ну или наличие полей в классе... если я все правильно понял) Очень хочется этот класс не использовать.
В общем как выяснилось отсутствует понимание механизма взаимодействия представления с моделью.
Например что делают функции index Непонимающий? и parent Непонимающий?
Как опрашивается модель?

что есть на данном этапе

Таблица типа
oid;     id; p_id; p_type; o_ex
76391; 1; 1;     1;         3
76392; 2; 1;     1;         3
76393; 3; 1;     1;         3
76394; 4; 2;     1;         3
76395; 5; 3;     1;         3
83764; 6; 3;     1;         3

oid - это от движка PG. еще не определился нужны будут или нет но решил пока оставить.
id - первичный ключ (уникальный).
p_id - число соответствующее первичному ключу предка.
p_type - это тип (по нему будет определятся какая таблица должна подтягиваться к o_ex)
o_ex - id внешней таблицы.

модель на данном этапе получилась такой.

Шапка
Код
C++ (Qt)
#include <QAbstractItemModel>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QString>
#include <QDebug>
 
class QRVZTreeModel : public QAbstractItemModel
{
   Q_OBJECT
public:
   explicit QRVZTreeModel(QObject *parent = 0, int root = 0);
   explicit QRVZTreeModel(int root = 0);
   int root;
 
   QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) 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 col, const QModelIndex& index = QModelIndex() ) const;
   QModelIndex parent( const QModelIndex& index ) const;
   int rowCount( const QModelIndex& index = QModelIndex() ) const;
   int columnCount( const QModelIndex& index = QModelIndex() ) const;
   void reset();
   void inc(){DXc++;qDebug()<<"DX - "<<DXc;}
 
private:
   QSqlDatabase db;
   QSqlQuery *STree;
   int DXc;
 
signals:
 
public slots:
 
};
 

C плюшка
Код
C++ (Qt)
QRVZTreeModel::QRVZTreeModel(QObject *parent, int root):QAbstractItemModel(parent){
 
}
 
QRVZTreeModel::QRVZTreeModel(int root){
   this->root = root;
   db = QSqlDatabase::database();
   STree = new QSqlQuery();
   STree->exec(QString("SELECT * FROM test.tr ORDER BY tr_id"));
   STree->first();
   DXc = 0;
}
 
QVariant QRVZTreeModel::data( const QModelIndex& index, int role) const{
   if(role == Qt::DisplayRole){
       if(index.isValid()){
           STree->seek(index.internalId());
           return STree->value(0);
       }
   }
   return QVariant();
}
 
QVariant QRVZTreeModel::headerData( int section, Qt::Orientation orientation, int role) const{
   if( orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0 )
       return QVariant(QString("name_tree"));
   return QVariant();
}
 
QModelIndex QRVZTreeModel::index( int row, int col, const QModelIndex& index) const{
   int count_chi = 0;
   int parent = root;
   if(index.isValid()){
       STree->seek(index.internalId());
       parent = STree->value(0).toInt();
       STree->first();
       for(int i = 0; i < STree->size(); i++){
           if (STree->value(1).toInt() == parent && STree->value(0)!=root){
               if(count_chi == row)return createIndex(row, col, STree->at());
               count_chi++;
           }
           STree->next();
       }
       return QModelIndex();
   }else{
       STree->first();
       for(int i = 0; i < STree->size(); i++){
           if (STree->value(1).toInt() == parent){
               if(count_chi == row)return createIndex(row, col, STree->at());
               count_chi++;
           }
           STree->next();
       }
   }
   return createIndex(row, col, 0);
}
 
QModelIndex QRVZTreeModel::parent( const QModelIndex& index) const{
   if(index.isValid()){
       STree->seek(index.internalId());
       if(STree->value(0).toInt() == root) return QModelIndex();
       int parent = STree->value(1).toInt();
       STree->first();
       for(int i = 0; i < STree->size(); i++){
           if (STree->value(0).toInt() == parent){
               int pid = STree->value(1).toInt();
               int rr = 0;
               STree->first();
               for(int j = 0; j < STree->size();j++){
                   if (STree->value(1).toInt() == pid){
                       if(STree->value(0).toInt() == parent && STree->value(1).toInt() == pid){
                           return createIndex(rr, 0, STree->at());
                       }
                       rr++;
                   }
                   STree->next();
               }
           }
           STree->next();
       }
   }
   return QModelIndex();
}
 
int QRVZTreeModel::rowCount( const QModelIndex& index) const{
   int parent = root;
   int count = 0;
   if(index.isValid()){
       STree->seek(index.internalId());
       parent = STree->value(0).toInt();
       STree->first();
       for(int i = 0; i<STree->size(); i++ ){
           if(STree->value(1) == parent && STree->value(0)!=root) count++;
           STree->next();
       }
       return count;
   }
   STree->first();
   for(int i = 0; i<STree->size(); i++ ){
       if(STree->value(0) == root) count++;
       STree->next();
   }
   return count;
}
 
int QRVZTreeModel::columnCount( const QModelIndex& index) const{
   return 1;
}
 
void QRVZTreeModel::reset(){
   STree->clear();
   STree->exec(QString("SELECT * FROM test.tr ORDER BY tr_id"));
   STree->first();
}
 

Она просто зацикливаться ни как не хотит увеличиваться номер строки передаваемый в функцию index
Что делать где лечить?Непонимающий

P.S. Заранее всем спасибо.
« Последнее редактирование: Июнь 03, 2012, 23:47 от RVZ » Записан
RVZ
Гость
« Ответ #3 : Июнь 03, 2012, 23:45 »

Ура товарищи я ЕЕ победил.
итак помогла информация расположенная тут - http://doc.crossplatform.ru/qt/4.5.0/model-view-model.html на мой взгляд самое точное описание и руководство.
само определение скопирую что бы было под рукой (то есть тут)

Цитировать
Резюме концепций

    * Модельные индексы дают представлениям и делегатам информацию о размещении элементов, предоставляемых моделью, и независимую от структуры данных.
    * Элементы определяются номерами строк и столбцов и модельным индексом их родительских элементов.
    * Модельные индексы создаются моделями по требованию других компонентов, таких как представления и делегаты.
    * Если при вызове функции index() в качестве родительского элемента передается действительный модельный индекс, то возвращаемый индекс ссылается на элемент, находящийся ниже в иерархии модели, чем родитель. Полученный индекс ссылается на дочерний элемент этого индекса.
    * Если в качестве родительского элемента функции index() передается недействительный модельный индекс, то возвращаемый индекс ссылается на элемент верхнего уровня.
    * Роль различается для различных видов данных, связанных с элементом.

что бы не плодить лишних кодов исправлю текст исходника в предыдущем посте.

на данный момент модель осуществляет навигацию по приведенной таблице нормально (правда столбец пока только один... но модель в разработке :-) ).
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #4 : Июнь 04, 2012, 20:21 »

Есть посвежее:
http://qt-project.org/doc/qt-4.8/modelview.html.
http://qt-project.org/doc/qt-4.8/examples-itemviews.html - документированные примеры (со звездочкой).
Еще полезная статья http://doc.trolltech.com/qq/qq10-mvc.html (перевод-http://wiki.crossplatform.ru/index.php/Реализация_Model/View/Controller) иллюстрирующая, например, как переустанавливать обработчики сигналов.

Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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