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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: TreeView AbstractItemModel и перемещение ветки  (Прочитано 4574 раз)
Boris
Гость
« : Сентябрь 23, 2009, 15:43 »

Делаю все как в qt\examples\itemviews\editabletreemodel, но нужно реализовать перемещение веток(с дочерними) вместе. Любой ценой можно с драгдроп можно без. По форуму листал не помогло. Прошу помочь советом.

Особо интересует как отрехтовать класс TreeItem чтобы в нем можно было двигать ветки.
Записан
Vass
Гость
« Ответ #1 : Сентябрь 23, 2009, 16:25 »

Если в кратце то вот то получается, TreeItem у вас содержит лист чилдов, т.е по идее чтобы переместить ветку вам надо, из одного листа удалить чилда, а в другой добавить.

Код:
virtual bool dropMimeData ( const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent )

он вызывается когда что-то куда-то дропиться.
parent - это индекс элемента на которой дропнули.
data - это то что дропнули, формат данных в data Вы можете определить сами переопределив функцию:
Код:
virtual QMimeData * mimeData ( const QModelIndexList & indexes ) const

Далее Вы осуществляете разбор данных и соответственно из них извлекаете информацию о том что дропнули,

Когда у вас есть инфа, что дропнули и есть инфа куда дропнули, Вы смело можете переносить это путем переноса указателя на чилда из листа старого родителя в лист нового
« Последнее редактирование: Сентябрь 23, 2009, 16:32 от Vass » Записан
Boris
Гость
« Ответ #2 : Сентябрь 23, 2009, 16:48 »

Спасибо я это и пробую... что-то у меня не работает.
TreeItem один в один как в примере за исключением. Код я тут на форуме позаимствовал
Код:
bool TreeItem::Move(int to, TreeItem *item)
{
   if (to < 0 || to > item->childItems.size())
       return false;

    int num;
    /*получаем номер текуцего потомка в списке потомков родителя*/
    num = childNumber();

   /*изменяем родителя у текущего элемента*/
    parentItem = item;

    /*добавляем текущий элемент в список нового родителя в указанную  позицию*/
    item->childItems.insert(item->childItems.size(),this);
    parentItem->childItems.removeAt(num);
    //delete parentItem->childItems.takeAt(num);
    return true;
}
наследник QAbstractItemModel
Код:
bool TreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
    QString arg = QString(data->data("application/x-qabstractitemmodeldatalist").data());
    int val = arg.toInt();
    qDebug() << "Ultimate" << (void*)val;
    TreeItem * tmp = static_cast<TreeItem *>((void*)val);
    TreeItem * parentTmp = static_cast<TreeItem *>(parent.internalPointer());
    tmp->Move(parentTmp->childCount(), parentTmp);
}

Qt::DropActions TreeModel::supportedDropActions () const
{
    return Qt::CopyAction | Qt::MoveAction ;
}

QStringList TreeModel::mimeTypes() const
{
    QStringList types;
    types << "application/x-qabstractitemmodeldatalist";
    return types;
}

QMimeData *TreeModel::mimeData(const QModelIndexList &indexes) const
 {
  qDebug() << "Size" << indexes.size();
  QMimeData * ret = new QMimeData;
  qDebug() << "Ultimate" << indexes.at(0).internalPointer();
  int a = (int)indexes.at(0).internalPointer();
  qDebug() << "a is " << a;
  QString result;
  QTextStream(&result) << a;
  qDebug() << result;
  TreeItem * tmp = static_cast<TreeItem *>(indexes.at(0).internalPointer());
  ret->setData("application/x-qabstractitemmodeldatalist", QByteArray(result.toAscii()));
  return ret;
}

Когда перетаскиваешь не обновляется TreeView (на месте откуда перетащил пелая строка остается)
Если у TreeItem есть скажем два дочерних итема и хочешь скинуть верхний во второй (те чтобы верхний дочерний стал дочерним второго дочернего) вываливается error.

Такой вопрос здесь уже задавался его так и не решили. примеров я не нашел.
« Последнее редактирование: Сентябрь 23, 2009, 16:51 от Boris » Записан
Vass
Гость
« Ответ #3 : Сентябрь 23, 2009, 17:14 »

Так обновляете модель то, после того как перенесли, например так:
Код:
emit layoutChanged();
например в конце dropMimeData

------------------------------------

А поповоду ошибок, ищите, где-то указатель теряется, кстати вот здесь:
Код:
  item->childItems.insert(item->childItems.size(),this);
    parentItem->childItems.removeAt(num);
Я бы рекомендовал сначала удалять, а потом добавлять, а то у Вас может что-нибудь нехорошее получиться когда один и тот же айтем в двух разных списках лежит.
И удалять рекомендовал бы через
Код:
removeOne(TreeItem* );
« Последнее редактирование: Сентябрь 23, 2009, 17:31 от Vass » Записан
Boris
Гость
« Ответ #4 : Сентябрь 24, 2009, 07:54 »

Спасибо, но все равно не то. Если ветку перетягиваешь в другие более нижние ветки, то она просто пропадает

И еще такой вопрос в dropMimeData возвращаю false, а в treeView все равно происходит перетаскивание.

Да и еще там insertRows/removeRows отрабатывают, так когда вниз тянешь insertRows не отрабатывает а ремов делает свое дело
« Последнее редактирование: Сентябрь 24, 2009, 11:14 от Boris » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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