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

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

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: Задача на тему Model/View  (Прочитано 26511 раз)
evilguard
Гость
« Ответ #15 : Февраль 19, 2007, 11:55 »

itan
Спасиб!!! Глянул сорцы, QTreeWidget, это то что мне нужно!!! Буду копать!!!
И можешь мне ответить на перваый вопрос в предыдущем посте, как лучше организовать модель при мой системе хранения данных в программе?
Записан
itan
Гость
« Ответ #16 : Февраль 19, 2007, 14:48 »

Цитата: "evilguard"
itan
Спасиб!!! Глянул сорцы, QTreeWidget, это то что мне нужно!!! Буду копать!!!
И можешь мне ответить на перваый вопрос в предыдущем посте, как лучше организовать модель при мой системе хранения данных в программе?


Каждый TreeItem должен хранить указатель на твой CObject - это нормально. Таким образом модель CTreeModel, получая указатель на текущий TreeItem в методе QVariant CTreeModel::data(const QModelIndex &index, int role) const
например так:
Код:
if (!index.isValid())
return QVariant();

CTreeItem *item = static_cast<CTreeItem*>(index.internalPointer());
...

может выводить информацию о соответствующем объекте CObject.
например так:
Код:
if (role == Qt::DisplayRole || role == Qt::EditRole)
{
       switch (index.column())
          {
           case 0: return item->data(0).toString();
           case 1: return item->data(1).toString();
           case 2: return item->data(2).toString();
          }
}

Код:
QVariant CTreeItem::data(int column)
{
        switch (column)
          {
           case 0: return pointer->caption();
           case 1: return pointer->type();
           case 2: return pointer->coord();  
          }
   return QVariant();
}

В модели CTreeModel делаешь метод типа void setupModelData(const QVector <CObject*>& objectList);
который вызываешь сразу после ее создания. В этом методе и происходит заполнение модели данными, например так:
Код:

rootItem = new CTreeItem(0);
foreach( CObject* obj, objectList)
{
       CTreeItem* newTreeItem = 0;
       newTreeItem = new CTreeItem(obj, rootItem);
       rootItem.appendChild(newTreeItem);
}

и не забываем про деструктор:
Код:
CTreeModel::~CTreeModel()
{
delete rootItem;
}
Записан
evilguard
Гость
« Ответ #17 : Февраль 20, 2007, 22:18 »

В общем перепахал весь форум, а проблема не снялась:( При добавлении новых элементов QTreeView почему-то не обновляется(хотя если добавлять элементы в модель сразу после создания, то они отображаются). Хотя я делаю:
Код:

connect(model, SIGNAL(rowsInserted(QModelIndex, int, int)),
ui.objectList, SLOT(rowsInserted(QModelIndex, int, int)));

Все равно, при добавлении нового элемента, от последнего элемента появляется кусочек линии, который должен подходить к новому элементу, однако, новый элемент не появляется. Его можно увидеть только вызвав для QTreeView функцию reset. Вот текст двух функций класса модели, отвечающих за добавление нового элемента, подсмотрены в QTreeWidget:
Код:

QModelIndex TreeModel::index(const TreeItem *item, int column) const
{
if (!item || (item == rootItem))
return QModelIndex();
const TreeItem *par = item->parent();
TreeItem *itm = const_cast<TreeItem*>(item);
if (!par)
par = rootItem;
return createIndex(par->children.lastIndexOf(itm), column, itm);
}

bool TreeModel::appendTopLevelItem(TreeItem *item)
{
beginInsertRows(index(rootItem, 0), rootItem->children.count(), rootItem->children.count());
rootItem->children.append(item);
item->parentItem=rootItem;
endInsertRows();
    return true;
}
Записан
evilguard
Гость
« Ответ #18 : Февраль 21, 2007, 16:34 »

Ну неужели никто не делал модели для QTreeView? Почему не обновляется виджет при добавлении элементов?
Записан
Вячеслав
Гость
« Ответ #19 : Февраль 21, 2007, 19:11 »

Model/View Programming Inserting and Removing Rows в ассистанте читал ?
Записан
evilguard
Гость
« Ответ #20 : Февраль 21, 2007, 20:08 »

Цитата из ассистанта:

Inserting and Removing Rows
It is possible to change the number of rows and columns in a model. In the string list model it only makes sense to change the number of rows, so we only reimplement the functions for inserting and removing rows. These are declared in the class definition:
     bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex());
     bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex());
Since rows in this model correspond to strings in a list, the insertRows() function inserts a number of empty strings into the string list before the specified position. The number of strings inserted is equivalent to the number of rows specified.
The parent index is normally used to determine where in the model the rows should be added. In this case, we only have a single top-level list of strings, so we just insert empty strings into that list.
Код:

 bool StringListModel::insertRows(int position, int rows, const QModelIndex &parent)
 {
     beginInsertRows(QModelIndex(), position, position+rows-1);

     for (int row = 0; row < rows; ++row) {
         stringList.insert(position, "");
     }

     endInsertRows();
     return true;
 }

The model first calls the beginInsertRows() function to inform other components that the number of rows is about to change. The function specifies the row numbers of the first and last new rows to be inserted, and the model index for their parent item. After changing the string list, it calls endInsertRows() to complete the operation and inform other components that the dimensions of the model have changed, returning true to indicate success.

Все тоже самое, что у меня, однако не работает Грустный Также вызывал endInsertRows(), но никаких сигналов в виджет не посылается...
Записан
Вячеслав
Гость
« Ответ #21 : Февраль 21, 2007, 21:25 »

Завтрева на работе погляжу - усе работало Подмигивающий С modelIndex'ами косяка не спорол ?
Записан
evilguard
Гость
« Ответ #22 : Февраль 21, 2007, 21:32 »

modelIndex - это я честно говоря не разобрался что такое. Я сделал класс TreeItem, как в книжке Бланшета, потому что мне нужно пару переменных объявить в классе элемента модели. Для чего вообще нужен QModelIndex?
Записан
Вячеслав
Гость
« Ответ #23 : Февраль 21, 2007, 21:56 »

гы Подмигивающий таки оно и показывает хто есть хто в данном случае Подмигивающий Короче определяет порядок следования записей ....
Этот кусок
Код:

An example usage of QStandardItemModel to create a tree:
 QStandardItemModel model;
 QStandardItem *parentItem = model.invisibleRootItem();
 for (int i = 0; i < 4; ++i) {
     QStandardItem *item = new QStandardItem(QString("item %0").arg(i));
     parentItem->appendRow(item);
     parentItem = item;
 }
видел ?  Как это разворачиваеться внутри модели - муторно но понять можно Подмигивающий
PS Опять-же сюда можно глянуть Model/View Programming / Model Classes
Записан
evilguard
Гость
« Ответ #24 : Февраль 21, 2007, 22:54 »

Вячеслав
Короче я ступил, офигенно, реализовал метод appendTopLevelItem из листинга 7 постами выше, а применить ее забыл, так и использовал простое добавление в контейнер))) Спасибо за помощь!!

добавлено спустя 7 минут:

 ура!!, я самовар!
Записан
evilguard
Гость
« Ответ #25 : Март 12, 2007, 17:23 »

Чем больше пытаюсь разобраться с Model/View, тем меньше понятно. Объясните пожалуйста зачем нужен QModelIndex, как он связан с ModelItem - класс, который определяешь сам, зачем нужен QVariant и как вообще хранятся данные в модели. Абсолютно ничегоне понятно.
Записан
AYK
Гость
« Ответ #26 : Март 12, 2007, 18:27 »

Цитата: "evilguard"
Чем больше пытаюсь разобраться с Model/View, тем меньше понятно. Объясните пожалуйста зачем нужен QModelIndex, как он связан с ModelItem - класс, который определяешь сам, зачем нужен QVariant и как вообще хранятся данные в модели. Абсолютно ничегоне понятно.


наверное очень быстро пытаешься разобраться. и видимо не до конца понял начальные моменты. Это как в высшей математике: пропустил одну пару и дальше ничего уже не понятно :lol:

Честно говоря я несколько раз перечитывал весь овервью по Модел/Вью классам, перечитывал листинги из примеров и опнемногу все дошло. А когда дошло, то понял насколько классная и продуманная система. И что самое главное ты можешь ее дорабатывать "под себя" очень легко и быстро.

QModelIndex - класс для ссылки на ячейку в какой либо модели - т.е.  это абсолютный адрес квартиры в многоэтажном доме. Из этого класса ты получаешь все: и в каком доме(модель) и в каком подъезде(родитель ячейки) и на каком этаже(строка) и номер квартиры(столбец)

QVariant - просто подарок для программистов!!!
Дело в том, что при создании универсальных классов или работе с базами данных без этого класса очень трудно обойтись.
Пример очень простой: у тебя есть функция которая получает один параметр. Тип параметра ты заранее не знаешь. Как поступить?
Раньше бы я объявил несколько функций с разными типами параметров. Благодаря QVariant теперь можно объявить одну функцию с параметров типа QVariant.
Из QVariant ты можешь уже получить всю информацию о параметре и преобразовать к нужному типу и многое другое.

Как храняться данные в модели?
В конечном итоге данные ячеек храняться в QVariant - это для универсальности. Нужно также понимать, что модель это не всегда что-то симметричное. Можно в качестве примера привести обычное дерево. Которое может расти в зависимости от обстоятельств (твоих потребностей) в разные стороны по разному. Т.е. абстрактная модель предоставляет возможность создать хранилище данных, в котором начиная с каждой новой ветки можно использовать разное количество столбцов. Нужно также понимать, что новая ветка может расти из любой ячейки модели, иначе говоря каждая ячейка модели может быть родителем новой ветки.

если коротко, то вот так...
Записан
evilguard
Гость
« Ответ #27 : Март 12, 2007, 19:07 »

А у тебя нет какого-нибудь примера древоаидной модели? Чтобы элементы были чекабильные. А то я пытаюсь разобраться в исходниках QTreeWidget, но понятно мало чего, нужен пример попроще.
Записан
Sergey B.
Программист
*****
Offline Offline

Сообщений: 544



Просмотр профиля WWW
« Ответ #28 : Март 12, 2007, 19:45 »

Цитата: "evilguard"
А у тебя нет какого-нибудь примера древоаидной модели? Чтобы элементы были чекабильные. А то я пытаюсь разобраться в исходниках QTreeWidget, но понятно мало чего, нужен пример попроще.



http://www.mechta34.com/it/qt4/

Сходи сюда...
Тут про модели хорошо рассказано. Правда сжато, но по русски Улыбающийся
Записан
evilguard
Гость
« Ответ #29 : Март 12, 2007, 20:25 »

Чем больше читаю, тем больше не понимаю. Конкретно спрошу. Хочу сделать item чекабильным. В первой колонке. Флаг установил - ItemIsUserCheckable. Поле для галочки появилось. Теперь мне надо что-то написать в методах data и setData модели. Написал, только, когда жму на галочку, она не появляется, ничего не происходит:
Код:

bool TreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid())
return false;
TreeItem *itm = itemFromIndex(index);
if (itm)
{
itm->checked = value.toInt()!=0 ? true : false;
return true;
}
return false;
}

QVariant TreeModel::data(const QModelIndex &index, int role) const
{
TreeItem *item = itemFromIndex(index);

if (role == Qt::CheckStateRole)
return item->checked ? Qt::Checked : Qt::Unchecked;

if (role == Qt::DisplayRole)
return item->pointer->objectName;
static QIcon folder(QPixmap("images/folder.png"));
if (role == Qt::DecorationRole)
return folder;
return QVariant();  
}


добавлено спустя 2 минуты:

 у TreeItem - моего класса есть булевское поле - checked.
Что собственно я не так делаю?

добавлено спустя 3 минуты:

 Только что ошибку нашел, поле не было userCheckable оказывается. Хотя checkbox отображался. Наконец начал что-то понимать по моделям )
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


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