PDA

View Full Version : RemoveRows



Untersander
9th January 2006, 10:46
Hi,

I want to remove rows in a QTreeView. I do that with:

beginRemoveRows(parentIndex, row, erow);
// erase data in the branch
endRemoveRows();


This is working as long the row to remove is not selected. If it's selected I get a access violation.

It doesnt help moving the selected and current item to a neighboured one before removing.

gadnio
9th January 2006, 11:59
if removing the selected row, you should do the code inside a shell like this:


if ( item->isSelected() )
QTimer::singleShot( 0, this, SLOT( my_slot_that_deletes_the_selected_item() ) );

Untersander
9th January 2006, 14:54
Thank you, gadnio,

I have tried, but have the same effect.
Should the slot 'my_slot_that_deletes_the_selected_item()' contain the begin- and endRemoveRows or should this be done outside

With putting in more checke in the parent() function of my model I most come through the deleting, but this is satisfying.

wysota
9th January 2006, 15:05
Could you show us the whole function used to remove rows and the context where it is used?
I didn't have any trouble removing a selected item...

Untersander
9th January 2006, 15:50
This is the Remove function:



bool GeometryModel::removeRows(int row, int count, const QModelIndex &parent)
{
bool done = false;
GeometryItem *parentItem;

if (parent.isValid()) {
parentItem = static_cast<GeometryItem*>(parent.internalPointer());
if (parentItem) {
parentItem = parentItem->parent();
if (parentItem) {
QModelIndex parentIndex = parent.parent();
int nc = parentItem->childCount();
if (row < 0) row = 0;
if ((row < nc) && (count > 0)) {
int erow = row + count - 1;
if (erow >= nc) erow = nc - 1;
beginRemoveRows(parentIndex, row, erow);
done = true;
while (done && (row <= erow)) {
selectedItem = parentItem;
selectedRow = erow;
done = parentItem->removeChild(erow);
erow--;
}
endRemoveRows();
}
}
}
}
return done;
}


And this is how it's called:


void TreeView::deleteSelectedItems()
{
QItemSelectionModel *selections = selectionModel();
QModelIndexList selIndexes = selections->selectedIndexes();
GeometryModel* gModel = (GeometryModel*)model();

void *ip_mom = NULL;
int row_mom = -1;

for (int i = 0; i < selIndexes.count(); i++) {
QModelIndex ri = selIndexes.at(i);
if ((ip_mom != ri.internalPointer()) || (row_mom != ri.row())) {
ip_mom = ri.internalPointer();
row_mom = ri.row();
gModel->removeRows(row_mom,1,ri);
}
}
}

The code is working with not selected branches

(This is my first QT-Project)

wysota
9th January 2006, 17:09
You have a little mess with all those parents and pointers :eek:

First few questions:


if (parent.isValid()) {
What is parent is not valid (which is true for top level model items)?


parentItem = static_cast<GeometryItem*>(parent.internalPointer());
if (parentItem) {

This will always be true (provided that you have a correct index() method in your model) but may be incorrect -- are you sure parent was not deleted before current item is deleted? While deleting an item you have to delete all its children first and not try to delete them after the parent item is deleted (so remove all references to them) and I don't see you do that in your code (and I guess it is hierarchical if you reference parent-child relation).


int nc = parentItem->childCount();
if parentItem is invalid (and my guess is it is invalid) this will cause a segfault.

My general hint is that you try to avoid all these references to parents and grandparents.

I see another problem too:


#
QItemSelectionModel *selections = selectionModel();
QModelIndexList selIndexes = selections->selectedIndexes();

The last call may return indexes which are selected, but they may be (I don't know, please check that) indexes from the selection model and not the base model! And you're using them as indexes from the base model:


QModelIndex ri = selIndexes.at(i);
//...
gModel->removeRows(row_mom,1,ri);

You should build an index from the "gModel" from data obtained from the selection model.

Untersander
11th January 2006, 10:44
You were right with the bad mixing of selection and model indexes. I have cleared this.
And I also have thrown the grandparents out of the family, my code is much shorter and looks better now.

Nevertheless I still had a crash after deleting a selected branch and have solved this by not deleting the removed branches immediately, I have put them into a trash, which can be cleared later. That's no problem, I have to keep these items anyway for undo functions.

After that I still came into a eternal loop after removing a top level subbranch, this I have solved by clearing the selection before removing.

The whole thing seems to be stable now.

Thank you very much for your suggestions.

Best regards,

Hans