Название: Задача на тему Model/View Отправлено: fear от Август 27, 2006, 18:35 Есть модель-дерево:
root | |--- item A | +--- item B | | | |--- item ca | | | |--- item cb | | | |--- item cc | +--- item C | |--- item ca | |--- item cb Вопрос: как изменить данные у item cb? Название: Задача на тему Model/View Отправлено: Admin от Август 27, 2006, 20:58 когда ты добавляешь элемент в модель
типа так parents->last()->appendChild(new CRegItemSection(&it_s->second,parents->last())); то у элемента всегда будет parent так что раскручивая его, ты можешь добратся до любого элемента Название: Задача на тему Model/View Отправлено: fear от Август 28, 2006, 12:39 Вопрос следующий:
есть ф-ция bool QAbstractItemModel::setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole ), с помощью которая задумана для изменения значений элементов модели, но ей нужно передать индекс элемента Вопрос в том как получить индекс? Есть ф-ция QModelIndex QAbstractItemModel::createIndex ( int row, int column, void * ptr = 0 ) const, но что бы ей воспользоваться как я понимаю нужен указатель на элемент модели. Название: Задача на тему Model/View Отправлено: itan от Август 28, 2006, 12:59 Индекс обычно сама модель и должна возвращать по средством метода virtual QModelIndex index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const = 0, который нужно самому переопределить.
Вот как это делается в примере Simple Tree Model Example Код: QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) Название: Задача на тему Model/View Отправлено: fear от Август 28, 2006, 20:36 Цитата: "itan" Индекс обычно сама модель и должна возвращать по средством метода virtual QModelIndex index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const = 0, который нужно самому переопределить. Вот как это делается в примере Simple Tree Model Example Код: QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) А можешь по конкретней, как изменить данные у item cb? Где взять третий параметр ф-ции index()? Название: Задача на тему Model/View Отправлено: itan от Август 29, 2006, 08:33 Все очень хорошо показано в примере $QTDIR/examples/itemviews/simpletreemodel, он же с комментариями описан в Assistant'се.
Для твоего случая: Код: QVariant value; Третий параметр в index это parent твоего элемента, корень дерева (root) всегда равен QModelIndex() т.к. parent у item cb является корнем дерева, то его мы не задаем (это параметр по умолчанию). Название: Задача на тему Model/View Отправлено: fear от Август 29, 2006, 14:12 Цитата: "itan" Все очень хорошо показано в примере $QTDIR/examples/itemviews/simpletreemodel, он же с комментариями описан в Assistant'се. Для твоего случая: Код: QVariant value; Третий параметр в index это parent твоего элемента, корень дерева (root) всегда равен QModelIndex() т.к. parent у item cb является корнем дерева, то его мы не задаем (это параметр по умолчанию). Ты привел пример не по теме. Вопрос в том как изменить значение элемента дерева у которого parent не является корнем дерева. Parent у item cb (item B) не является корнем дерева. Название: Задача на тему Model/View Отправлено: itan от Август 29, 2006, 16:48 Принципиальной разницы в том является parent корнем или не является нет.
Если ты действуешь из модели (TreeModel), то она должна хранить в себе корень дерева - rootItem и уже раскручивая его ты можешь добраться до любого элемента и изменить его. Если же ты действуешь из вьюхи (QTreeView, например), то просто получаешь currentIndex() и суешь его в функцию setData() твоей модели (хотя в этом случае лучше организовать редактирование через делегаты). Название: Задача на тему Model/View Отправлено: bigirbis от Август 30, 2006, 13:04 ИМХО, вообще достаточно странный БАЗАР.
Родителя индекс получает или во время создания, или после репарента. Поэтому, родителя всегда можно вытащить при помощи: QModelIndex QModelIndex::parent () const Что касается метода QModelIndex QAbstractItemModel::index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const ,то он как правило для internal использования и создан для того, чтобы создавать индексы на основе структур данных модели. И не надо знать, что это за третий аргумент - он просто входной! Название: Задача на тему Model/View Отправлено: fear от Сентябрь 03, 2006, 13:18 Всем спасибо, вкурил я что к чему.
Появился другой вопрос ... В моё модель-дерево пользователь может добавлять элементы, что бы новые элементы отображались сразу после добавления я так понимаю надо генерировать сигнал void QAbstractItemModel::rowsInserted ( const QModelIndex & parent, int start, int end ), а компилятор пишет что ф-ция private:
Так как быть? Или я использую не правильный подход? Название: Задача на тему Model/View Отправлено: noosooth от Сентябрь 03, 2006, 17:21 Код:
Note: Components connected to this signal use it to adapt to changes in the model's dimensions. It can only be emitted by the QAbstractItemModel implementation, and cannot be explicitly emitted in subclass code. Eсли Ваша модель умеет добавлять строки, то Вы должны были реализовать что-то вроде: Код:
QAbstractItemModel::endInsertRows(), насколько я понимаю, и посылает сигнал rowsInserted(). Этот сигнал уже должен быть соединён со слотом rowsInserted() Вашего View в момент вызова Код:
Разве не так? Название: Задача на тему Model/View Отправлено: fear от Сентябрь 07, 2006, 16:14 Спасибо всем за помощь
Название: Задача на тему Model/View Отправлено: evilguard от Февраль 17, 2007, 22:52 Решил не плодить топики, запостю сюда, благо у меня тоже задача по Model/View. Пишу программу которая графически отображает какие-то сложные объекты: пусть к примеру это будут круги, линии, точки, соответственно CCircle, CLine, CPoint. Они все унаследованы от одного класса, к примеру CObject. В программе могут встерчаться объекты всех трех типов в разных количествах совершенно независимо друг от друга. Поэтому я храню объекты в таком виде:
Код:
Хочу теперь чтобы все эти объекты отображались в QTreeView, в виде дерева, чтобы их можно было группировать в папки. Посмотрел какие есть примеры, по QABstractItemModel, содрал код примера simpletreemodel. Помогите пожалуйста как организовать модель. Пока у меня есть только 1 вариант: хранить в каждом элементе модели указатель на объект: Код:
Но че-то мне этот способ не очень нравится.. Поделитесь пожалуйста соображениями. Заранее благодарен! добавлено спустя 3 часа 24 минуты: И подскажите пожалуйста, как добавлять элементы в модель?? Делаю динамическое добавление вот так: Код:
Так вот, если таким образом добавлять в корневой item модели, то не происходит обновления в QTreeView, визуально это выглядит так: от последнего элемента в корневой папке отходит кусочек линии, а надпись не появляется. Если таким образом добавлять не в корневой item, а во вложенный то все аналогично, а надпись появляется тогда, когда закрываешь плюсиком верхний item, а затем открываешь, он становится виден. Что я не так делаю? Получается сам QTreeView Некорректно работает, не обновляется при изменении модели?? Название: Задача на тему Model/View Отправлено: evilguard от Февраль 18, 2007, 23:06 Ну пожалуйста помогите кто-нибудь!! Работа стоит, так и не разобрался как добавлять элементы в модель :(
Название: Задача на тему Model/View Отправлено: itan от Февраль 19, 2007, 09:58 Хорошим разъясняющим материалом может послужить пример взаимодействия QTreeWidget и QTreeWidgetItem (смотри исходный код). Или же QStandardItem и QStandardItemModel (QT4.2).
Название: Задача на тему Model/View Отправлено: evilguard от Февраль 19, 2007, 11:55 itan
Спасиб!!! Глянул сорцы, QTreeWidget, это то что мне нужно!!! Буду копать!!! И можешь мне ответить на перваый вопрос в предыдущем посте, как лучше организовать модель при мой системе хранения данных в программе? Название: Задача на тему Model/View Отправлено: itan от Февраль 19, 2007, 14:48 Цитата: "evilguard" itan Спасиб!!! Глянул сорцы, QTreeWidget, это то что мне нужно!!! Буду копать!!! И можешь мне ответить на перваый вопрос в предыдущем посте, как лучше организовать модель при мой системе хранения данных в программе? Каждый TreeItem должен хранить указатель на твой CObject - это нормально. Таким образом модель CTreeModel, получая указатель на текущий TreeItem в методе QVariant CTreeModel::data(const QModelIndex &index, int role) const например так: Код: if (!index.isValid()) может выводить информацию о соответствующем объекте CObject. например так: Код: if (role == Qt::DisplayRole || role == Qt::EditRole) Код: QVariant CTreeItem::data(int column) В модели CTreeModel делаешь метод типа void setupModelData(const QVector <CObject*>& objectList); который вызываешь сразу после ее создания. В этом методе и происходит заполнение модели данными, например так: Код:
и не забываем про деструктор: Код: CTreeModel::~CTreeModel() Название: Задача на тему Model/View Отправлено: evilguard от Февраль 20, 2007, 22:18 В общем перепахал весь форум, а проблема не снялась:( При добавлении новых элементов QTreeView почему-то не обновляется(хотя если добавлять элементы в модель сразу после создания, то они отображаются). Хотя я делаю:
Код:
Все равно, при добавлении нового элемента, от последнего элемента появляется кусочек линии, который должен подходить к новому элементу, однако, новый элемент не появляется. Его можно увидеть только вызвав для QTreeView функцию reset. Вот текст двух функций класса модели, отвечающих за добавление нового элемента, подсмотрены в QTreeWidget: Код:
Название: Задача на тему Model/View Отправлено: evilguard от Февраль 21, 2007, 16:34 Ну неужели никто не делал модели для QTreeView? Почему не обновляется виджет при добавлении элементов?
Название: Задача на тему Model/View Отправлено: Вячеслав от Февраль 21, 2007, 19:11 Model/View Programming Inserting and Removing Rows в ассистанте читал ?
Название: Задача на тему Model/View Отправлено: evilguard от Февраль 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. Код:
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(), но никаких сигналов в виджет не посылается... Название: Задача на тему Model/View Отправлено: Вячеслав от Февраль 21, 2007, 21:25 Завтрева на работе погляжу - усе работало ;) С modelIndex'ами косяка не спорол ?
Название: Задача на тему Model/View Отправлено: evilguard от Февраль 21, 2007, 21:32 modelIndex - это я честно говоря не разобрался что такое. Я сделал класс TreeItem, как в книжке Бланшета, потому что мне нужно пару переменных объявить в классе элемента модели. Для чего вообще нужен QModelIndex?
Название: Задача на тему Model/View Отправлено: Вячеслав от Февраль 21, 2007, 21:56 гы ;) таки оно и показывает хто есть хто в данном случае ;) Короче определяет порядок следования записей ....
Этот кусок Код:
PS Опять-же сюда можно глянуть Model/View Programming / Model Classes Название: Задача на тему Model/View Отправлено: evilguard от Февраль 21, 2007, 22:54 Вячеслав
Короче я ступил, офигенно, реализовал метод appendTopLevelItem из листинга 7 постами выше, а применить ее забыл, так и использовал простое добавление в контейнер))) Спасибо за помощь!! добавлено спустя 7 минут: ура!!, я самовар! Название: Задача на тему Model/View Отправлено: evilguard от Март 12, 2007, 17:23 Чем больше пытаюсь разобраться с Model/View, тем меньше понятно. Объясните пожалуйста зачем нужен QModelIndex, как он связан с ModelItem - класс, который определяешь сам, зачем нужен QVariant и как вообще хранятся данные в модели. Абсолютно ничегоне понятно.
Название: Задача на тему Model/View Отправлено: AYK от Март 12, 2007, 18:27 Цитата: "evilguard" Чем больше пытаюсь разобраться с Model/View, тем меньше понятно. Объясните пожалуйста зачем нужен QModelIndex, как он связан с ModelItem - класс, который определяешь сам, зачем нужен QVariant и как вообще хранятся данные в модели. Абсолютно ничегоне понятно. наверное очень быстро пытаешься разобраться. и видимо не до конца понял начальные моменты. Это как в высшей математике: пропустил одну пару и дальше ничего уже не понятно :lol: Честно говоря я несколько раз перечитывал весь овервью по Модел/Вью классам, перечитывал листинги из примеров и опнемногу все дошло. А когда дошло, то понял насколько классная и продуманная система. И что самое главное ты можешь ее дорабатывать "под себя" очень легко и быстро. QModelIndex - класс для ссылки на ячейку в какой либо модели - т.е. это абсолютный адрес квартиры в многоэтажном доме. Из этого класса ты получаешь все: и в каком доме(модель) и в каком подъезде(родитель ячейки) и на каком этаже(строка) и номер квартиры(столбец) QVariant - просто подарок для программистов!!! Дело в том, что при создании универсальных классов или работе с базами данных без этого класса очень трудно обойтись. Пример очень простой: у тебя есть функция которая получает один параметр. Тип параметра ты заранее не знаешь. Как поступить? Раньше бы я объявил несколько функций с разными типами параметров. Благодаря QVariant теперь можно объявить одну функцию с параметров типа QVariant. Из QVariant ты можешь уже получить всю информацию о параметре и преобразовать к нужному типу и многое другое. Как храняться данные в модели? В конечном итоге данные ячеек храняться в QVariant - это для универсальности. Нужно также понимать, что модель это не всегда что-то симметричное. Можно в качестве примера привести обычное дерево. Которое может расти в зависимости от обстоятельств (твоих потребностей) в разные стороны по разному. Т.е. абстрактная модель предоставляет возможность создать хранилище данных, в котором начиная с каждой новой ветки можно использовать разное количество столбцов. Нужно также понимать, что новая ветка может расти из любой ячейки модели, иначе говоря каждая ячейка модели может быть родителем новой ветки. если коротко, то вот так... Название: Задача на тему Model/View Отправлено: evilguard от Март 12, 2007, 19:07 А у тебя нет какого-нибудь примера древоаидной модели? Чтобы элементы были чекабильные. А то я пытаюсь разобраться в исходниках QTreeWidget, но понятно мало чего, нужен пример попроще.
Название: Задача на тему Model/View Отправлено: Sergey B. от Март 12, 2007, 19:45 Цитата: "evilguard" А у тебя нет какого-нибудь примера древоаидной модели? Чтобы элементы были чекабильные. А то я пытаюсь разобраться в исходниках QTreeWidget, но понятно мало чего, нужен пример попроще. http://www.mechta34.com/it/qt4/ Сходи сюда... Тут про модели хорошо рассказано. Правда сжато, но по русски :) Название: Задача на тему Model/View Отправлено: evilguard от Март 12, 2007, 20:25 Чем больше читаю, тем больше не понимаю. Конкретно спрошу. Хочу сделать item чекабильным. В первой колонке. Флаг установил - ItemIsUserCheckable. Поле для галочки появилось. Теперь мне надо что-то написать в методах data и setData модели. Написал, только, когда жму на галочку, она не появляется, ничего не происходит:
Код:
добавлено спустя 2 минуты: у TreeItem - моего класса есть булевское поле - checked. Что собственно я не так делаю? добавлено спустя 3 минуты: Только что ошибку нашел, поле не было userCheckable оказывается. Хотя checkbox отображался. Наконец начал что-то понимать по моделям ) Название: Задача на тему Model/View Отправлено: vregess от Март 12, 2007, 20:30 В setData можно поставить
Код:
Таким образом ты скажешь, что данные модели изменились, и это изменение должно немедленно отобразиться. Кстати, по организации модели и хранения данный советую посмотреть исходники Qt Designer'a , а точнее его property editor'a. там все очень клево сделано, мне понравилось. И в принципе все понятно очень, хотя я не сразу врубился в некоторые методы, ну а потом все стало ясно. Идея хорошая, как и реализация. Название: Задача на тему Model/View Отправлено: evilguard от Март 12, 2007, 22:08 Цитата: "vregess" В setData можно поставить Код:
Таким образом ты скажешь, что данные модели изменились, и это изменение должно немедленно отобразиться. Хм, не понадобилось вставлять это, без сигнала заработало. добавлено спустя 16 минут: Кстати, все-таки непонятно, QModelIndex - это значит адрес ячейки модели. А как он выходит на реальный объект класса TreeItem, вот это мне непонятно. Как они связываются? добавлено спустя 52 минуты: И еще, как убрать заголовок у QTreeView? Название: Задача на тему Model/View Отправлено: Lion от Март 12, 2007, 22:43 Цитата: "evilguard" А у тебя нет какого-нибудь примера древоаидной модели? Чтобы элементы были чекабильные. А то я пытаюсь разобраться в исходниках QTreeWidget, но понятно мало чего, нужен пример попроще. Simple Tree Model Example в Assistant-е тебе в руки! Название: Задача на тему Model/View Отправлено: vregess от Март 12, 2007, 22:51 Цитата: "evilguard" Кстати, все-таки непонятно, QModelIndex - это значит адрес ячейки модели. А как он выходит на реальный объект класса TreeItem, вот это мне непонятно. Как они связываются? Цитировать QModelIndex QAbstractItemModel::createIndex ( int row, int column, void * ptr = 0 ) const [protected] Creates a model index for the given row and column with the internal pointer ptr. This function provides a consistent interface that model subclasses must use to create model indexes. Когда ты создаешь индекс, ты указываешь последним аргументом как раз TreeItem, таким образом в возвращаемом объекте QModelIndex хранятся строка, колонка и указатель на TreeItem. Непосредственно сам объект, на который указывает QModelIndex, можно получить используя метод internalPointer () этого класса. Посмотри документацию на QModelIndex. Еще раз повторю: В твоей реализации модели для QTreeView есть метод index. вот его описание: Цитировать QModelIndex QAbstractItemModel::index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const [pure virtual] Returns the index of the item in the model specified by the given row, column and parent index. Этот метод вызывается виджетом QTreeView (в твоем случае). Когда Виджету необходимо получить информацию о каком либо итеме он передает методу index строку, колонку и родительский индекс интересующего итема. Параметры row и column - это положение интересующего итема внутри Родителя. на Родителя показывает parent. Вот. Цитата: "evilguard" И еще, как убрать заголовок у QTreeView? В смысле? Название: Задача на тему Model/View Отправлено: evilguard от Март 12, 2007, 23:17 Цитата: "vregess" Цитата: "evilguard" И еще, как убрать заголовок у QTreeView? В смысле? В смысле шапку таблицы. Название: Задача на тему Model/View Отправлено: vregess от Март 13, 2007, 07:33 Цитата: "evilguard" Цитата: "vregess" Цитата: "evilguard" И еще, как убрать заголовок у QTreeView? В смысле? В смысле шапку таблицы. Код:
Цитировать QHeaderView * QTreeView::header () const Returns the header for the tree view. Название: Задача на тему Model/View Отправлено: evilguard от Март 19, 2007, 18:50 Искал по всей справке, но так и не нашел, как обработать нажатие кнопки мыши на Q***View. Где почитать про это можно?
Название: Задача на тему Model/View Отправлено: vregess от Март 19, 2007, 21:57 Цитата: "evilguard" Искал по всей справке, но так и не нашел, как обработать нажатие кнопки мыши на Q***View. Где почитать про это можно? Смотри доки по: void QWidget::customContextMenuRequested ( const QPoint & pos ) bool QAbstractScrollArea::event ( QEvent * e ) void QAbstractItemView::mouseDoubleClickEvent ( QMouseEvent * event ) void QAbstractItemView::mouseMoveEvent ( QMouseEvent * event ) void QAbstractItemView::mousePressEvent ( QMouseEvent * event ) void QAbstractItemView::mouseReleaseEvent ( QMouseEvent * event ) Название: Задача на тему Model/View Отправлено: evilguard от Март 20, 2007, 08:41 Еще вопросик: мне нужно, чтобы item'ы выделялись, причем самому определить способ их выделения, для QTreeView. По умолчанию он выделяет все подряд, а мне надо допустим, чтобы если я начал выделение через Ctrl или Shift, то должны добавляться к выделенным долько корневые элементы модели. А допустим, вложенных элементов нельзя выделить больше одной штуки(то есть выделяется только по клику мыши, но не клавишами Ctrl или Shift). Как отлавливать такое специфическое выделение.
Сейчас у меня стоит objectsList->setSelectionMode(QAbstractItemView::ExtendedSelection); |