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

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

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Задача на тему Model/View  (Прочитано 26317 раз)
fear
Гость
« : Август 27, 2006, 18:35 »

Есть модель-дерево:

root
|
|--- item A
|
+--- item B
| |
| |--- item ca
| |
| |--- item cb
| |
| |--- item cc
|
+--- item C
|
|--- item ca
|
|--- item cb

Вопрос: как изменить данные у item cb?
Записан
Admin
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1988



Просмотр профиля
« Ответ #1 : Август 27, 2006, 20:58 »

когда ты добавляешь элемент в модель
типа так

parents->last()->appendChild(new CRegItemSection(&it_s->second,parents->last()));

то у элемента всегда будет parent

так что раскручивая его, ты можешь добратся до любого элемента
Записан
fear
Гость
« Ответ #2 : Август 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, но что бы ей воспользоваться как я понимаю нужен указатель на элемент модели.
Записан
itan
Гость
« Ответ #3 : Август 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)
                const
    {
        TreeItem *parentItem;

        if (!parent.isValid())
            parentItem = rootItem;
        else
            parentItem = static_cast<TreeItem*>(parent.internalPointer());

        TreeItem *childItem = parentItem->child(row);
        if (childItem)
            return createIndex(row, column, childItem);
        else
            return QModelIndex();
    }
Записан
fear
Гость
« Ответ #4 : Август 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)
                const
    {
        TreeItem *parentItem;

        if (!parent.isValid())
            parentItem = rootItem;
        else
            parentItem = static_cast<TreeItem*>(parent.internalPointer());

        TreeItem *childItem = parentItem->child(row);
        if (childItem)
            return createIndex(row, column, childItem);
        else
            return QModelIndex();
    }


А можешь по конкретней, как изменить данные у item cb? Где взять третий параметр ф-ции index()?
Записан
itan
Гость
« Ответ #5 : Август 29, 2006, 08:33 »

Все очень хорошо показано в примере $QTDIR/examples/itemviews/simpletreemodel, он же с комментариями описан в Assistant'се.
Для твоего случая:

Код:
QVariant value;
TreeModel* treeModel;
...
QModelIndex cbIndex = treeModel->index(4, 0);
treeModel->setData(cbIndex, value);


Третий параметр в index это parent твоего элемента, корень дерева (root) всегда равен QModelIndex() т.к. parent у item cb является корнем дерева, то его мы не задаем (это параметр по умолчанию).
Записан
fear
Гость
« Ответ #6 : Август 29, 2006, 14:12 »

Цитата: "itan"
Все очень хорошо показано в примере $QTDIR/examples/itemviews/simpletreemodel, он же с комментариями описан в Assistant'се.
Для твоего случая:

Код:
QVariant value;
TreeModel* treeModel;
...
QModelIndex cbIndex = treeModel->index(4, 0);
treeModel->setData(cbIndex, value);


Третий параметр в index это parent твоего элемента, корень дерева (root) всегда равен QModelIndex() т.к. parent у item cb является корнем дерева, то его мы не задаем (это параметр по умолчанию).


Ты привел пример не по теме. Вопрос в том как изменить значение элемента дерева у которого parent не является корнем дерева.

Parent у item cb (item B) не является корнем дерева.
Записан
itan
Гость
« Ответ #7 : Август 29, 2006, 16:48 »

Принципиальной разницы в том является parent корнем или не является нет.
Если ты действуешь из модели (TreeModel), то она должна хранить в себе корень дерева - rootItem и уже раскручивая его ты можешь добраться до любого элемента и изменить его.
Если же ты действуешь из вьюхи (QTreeView, например), то просто получаешь currentIndex() и суешь его в функцию setData() твоей модели (хотя в этом случае лучше организовать редактирование через делегаты).
Записан
bigirbis
Гость
« Ответ #8 : Август 30, 2006, 13:04 »

ИМХО, вообще достаточно странный БАЗАР.
Родителя индекс получает или во время создания, или после репарента.
Поэтому, родителя всегда можно вытащить при помощи:
QModelIndex QModelIndex::parent () const

Что касается метода
QModelIndex QAbstractItemModel::index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const
,то он как правило для internal использования и создан для того, чтобы создавать индексы на основе структур данных модели.
И не надо знать, что это за третий аргумент - он просто входной!
Записан
fear
Гость
« Ответ #9 : Сентябрь 03, 2006, 13:18 »

Всем спасибо, вкурил я что к чему.

Появился другой вопрос ...
В моё модель-дерево пользователь может добавлять элементы, что бы новые элементы отображались сразу после добавления я так понимаю надо генерировать сигнал void QAbstractItemModel::rowsInserted ( const QModelIndex & parent, int start, int end ), а компилятор пишет что ф-ция private:

    error C2248: 'QAbstractItemModel::rowsInserted' : cannot access private member declared in class 'QAbstractItemModel'


Так как быть? Или я использую не правильный подход?
Записан
noosooth
Гость
« Ответ #10 : Сентябрь 03, 2006, 17:21 »

Код:

void QAbstractItemModel::rowsInserted ( const QModelIndex & parent, int start, int end )  [signal]

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сли Ваша модель умеет добавлять строки, то Вы должны были реализовать что-то вроде:
Код:

bool MyModel::insertRows(int pos, int rows, const QModelIndex &parent)
    {
        beginInsertRows(QModelIndex(), pos, pos+rows-1);
        ...
        endInsertRows();
        return true;
    }

QAbstractItemModel::endInsertRows(), насколько я понимаю, и посылает сигнал rowsInserted().
Этот сигнал уже должен быть соединён со слотом rowsInserted() Вашего View в момент вызова
Код:

QAbstractItemView::setModel(QAbstractItemModel * model))


Разве не так?
Записан
fear
Гость
« Ответ #11 : Сентябрь 07, 2006, 16:14 »

Спасибо всем за помощь
Записан
evilguard
Гость
« Ответ #12 : Февраль 17, 2007, 22:52 »

Решил не плодить топики, запостю сюда, благо у меня тоже задача по Model/View. Пишу программу которая графически отображает какие-то сложные объекты: пусть к примеру это будут круги, линии, точки, соответственно CCircle, CLine, CPoint. Они все унаследованы от одного класса, к примеру CObject. В программе могут встерчаться объекты всех трех типов в разных количествах совершенно независимо друг от друга. Поэтому я храню объекты в таком виде:
Код:

   vector <CObject*> objects;   // вектор указателей на базовый класс
   objects.push_back(new CPoint);   //добавление объектов
   objects.push_back(new CCircle);
   objects.push_back(new CLine);
   vector <CObject*>::iterator iter;
   for (iter=objects.begin(); iter!=objects.end; ++iter)
       (*iter)->Draw();     //Отображение объектов на экране, виртуальная функция Draw() переопределенная для каждого объекта

Хочу теперь чтобы все эти объекты отображались в QTreeView, в виде дерева, чтобы их можно было группировать в папки. Посмотрел какие есть примеры, по QABstractItemModel, содрал код примера simpletreemodel. Помогите пожалуйста как организовать модель. Пока у меня есть только 1 вариант: хранить в каждом элементе модели указатель на объект:
Код:

class TreeItem
{
public:
    TreeItem(const QList<QVariant> &data, TreeItem *parent = 0);
    ~TreeItem();

    void appendChild(TreeItem *child);

    TreeItem *child(int row);
    int childCount() const;
    int columnCount() const;
    QVariant data(int column) const;
    int row() const;
    TreeItem *parent();
    QList<TreeItem*> childItems;

    CObject *pointer;            //Указатель на объект
    Type type;                      //Тип объекта

private:
    TreeItem *parentItem;
};

Но че-то мне этот способ не очень нравится.. Поделитесь пожалуйста соображениями. Заранее благодарен!

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

 И подскажите пожалуйста, как добавлять элементы в модель??
Делаю динамическое добавление вот так:
Код:

TreeModel viewModel = new TreeModel();
                TreeItem* item = new TreeItem(viewModel->rootItem);
item->pointer = obj;
viewModel->rootItem->appendChild(item);

Так вот, если таким образом добавлять в корневой item модели, то не происходит обновления в QTreeView, визуально это выглядит так: от последнего элемента в корневой папке отходит кусочек линии, а надпись не появляется. Если таким образом добавлять не в корневой item, а во вложенный то все аналогично, а надпись появляется тогда, когда закрываешь плюсиком верхний item, а затем открываешь, он становится виден. Что я не так делаю? Получается сам QTreeView Некорректно работает, не обновляется при изменении модели??
Записан
evilguard
Гость
« Ответ #13 : Февраль 18, 2007, 23:06 »

Ну пожалуйста помогите кто-нибудь!! Работа стоит, так и не разобрался как добавлять элементы в модель Грустный
Записан
itan
Гость
« Ответ #14 : Февраль 19, 2007, 09:58 »

Хорошим разъясняющим материалом может послужить пример взаимодействия QTreeWidget и QTreeWidgetItem (смотри исходный код). Или же QStandardItem и QStandardItemModel (QT4.2).
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


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