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

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

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: beginRemoveRows не понятно как работает  (Прочитано 11587 раз)
ритт
Гость
« Ответ #15 : Июнь 30, 2009, 08:43 »

уж не задача ли это самой вьюхи - следить за селекшенами? вроде, персистент индексы ещё никто не отменял...
Записан
spectre71
Гость
« Ответ #16 : Июль 02, 2009, 10:27 »

уж не задача ли это самой вьюхи - следить за селекшенами? вроде, персистент индексы ещё никто не отменял...

Только отчасти, в случае когда не предпологается изменение данных при изменении селекции этот подход верен.
В моем случае это не так.
Данные, например клас TProject, имеет int itemIndex(void) и void itemIndex(int). Селекция во View всегда должна соответствовать itemIndex. При смене селекции должен устанавливаться itemIndex(int), а это мало того что тяжелая операция, она еще и не простая в плане синхронизации с другими данными. itemIndex может быть изменен как через View, так и из других мест! При удалении элементов из списка TProject может измениться itemIndex, в зависимости какой элемент удаляется, и механизм того как изменяется itemIndex встроен в TProject.
Теперь смотрим что получается:

Код
C++ (Qt)
 
......
 
 ProjectView = new TTableView(MainWindow);
 ProjectModel = new TProjectModel();
 ProjectView->setModel(ProjectModel);
 QObject::connect(ProjectModel, SIGNAL(signalUpdateSelection(const QModelIndex)), ProjectView, SLOT(setCurrentIndex(const QModelIndex)));
 QObject::connect(ProjectView->selectionModel(), SIGNAL(currentRowChanged (const QModelIndex &, const QModelIndex &)), ProjectModel, SLOT(onCurrentChanged (const QModelIndex &, const QModelIndex &)));
 
......
 
 ProjectModel->setProject(Project);
 ProjectModel->updateSelection();
 
......
 
void TProjectModel::onCurrentChanged (const QModelIndex & current, const QModelIndex & previous) {
 if(LockUpdateSelection) {return;}
 if(!current.isValid())  {Project->itemIndex(-1); return;}
 Project->itemIndex(current.row());
}
 
void TProjectModel::updateSelection(void) {
 if(Project->itemIndex() < 0) {return;}
 LockUpdateSelection++;
 emit signalUpdateSelection(this->index(Project->itemIndex(), 0, QModelIndex()));
 LockUpdateSelection--;
}
 
void TProjectModel::beginDeleteTask(int ind) {
 LockUpdateSelection++;
 beginRemoveRows(QModelIndex(), Project->itemIndex(), Project->itemIndex());
 LockUpdateSelection--;
}
 
void TProjectModel::endDeleteTask(void) {
 endRemoveRows();
 updateSelection();
}
 
.........................
 
void TPLProject::itemIndex(int ItemIndex) {
 CurTask   = task(ItemIndex);
 this->ItemIndex = ItemIndex;
 for(int i=0; i<TaskOrdered.count(); i++) {
   if(TaskOrdered.object(i) == CurTask) {
     TaskOrdered.move(i, 0);
     break;
   }
 }
 sync()->onTaskIndexChange();
}
 
void TPLProject::deleteTask(void) {
 if(ItemIndex == -1) {return;}
 resetTask();
 if(Task.count() == 1) {
   propertyEditor()->tree(NULL);
   clear();
   return;
 }
 int rem_ind  = ItemIndex;
 sync()->projectModel()->beginDeleteTask(rem_ind);
 try {
   if(ItemIndex == Task.count()-1) {ItemIndex--;}
   for(int i=0; i<Task.count(); i++) {
     if(task(i) == CurTask) {continue;}
     task(i)->deletePipe(CurTask);
   }
   Task.remove(rem_ind);
   for(int i=0; i<TaskOrdered.count(); i++) {
     if(CurTask != TaskOrdered.object(i)) {continue;}
     TaskOrdered.remove(i);
     break;
   }
   CurTask = task(ItemIndex);
 } catch (...) {
   sync()->projectModel()->endDeleteTask();
   throw;
 }
 sync()->projectModel()->endDeleteTask();
 
 updateScreenMax();
 pipelineEditor()->updateFieldSize();
 pipelineEditor()->repaint();
 propertyEditor()->tree(program()->tree());
}
 
 

Посмотри в TPLProject::deleteTask вызов метода модели  beginDeleteTask(rem_ind); и сам метод в модели!
Если не использовать блокировку, то получается:
при вызове beginRemoveRows(QModelIndex(), Project->itemIndex(), Project->itemIndex()); меняется селекция и вызывается TPLProject::itemIndex(int) и возникают большие неприятности.


уж не задача ли это самой вьюхи - следить за селекшенами? вроде, персистент индексы ещё никто не отменял...
Причем здесь персистент индексы, я не понял?
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


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