уж не задача ли это самой вьюхи - следить за селекшенами? вроде, персистент индексы ещё никто не отменял...
Только отчасти, в случае когда не предпологается изменение данных при изменении селекции этот подход верен.
В моем случае это не так.
Данные, например клас 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) и возникают большие неприятности.
уж не задача ли это самой вьюхи - следить за селекшенами? вроде, персистент индексы ещё никто не отменял...
Причем здесь персистент индексы, я не понял?