Re: [gtkmm] Erasing TreeModel rows...
- From: Matthew Walton <matthew alledora co uk>
- To: Dennis Craven <linuxnewb rogers com>
- Cc: gtkmm-list gnome org
- Subject: Re: [gtkmm] Erasing TreeModel rows...
- Date: Thu, 26 Feb 2004 07:30:01 +0000
Dennis Craven wrote:
Hey,
I've been following the documentation and examples online and in the
distribution. They are helpful, but a little unclear about removing rows
from TreeModels. Here is the function that I have attempting to do the
dirty work.
void MyTreeView::deleteRow(Glib::ustring title)
{
Gtk::TreeModel::Children children = treestore->children();
for(Gtk::TreeModel::Children::iterator iter = children.begin(); iter
!= children.end(); ++iter)
{
Gtk::TreeModel::Row row = *iter;
if (row[columns.m_col_name] == title) {
////
// Segfaults on this erase line. "treestore" is declared as
// Glib::RefPtr<Gtk::TreeStore> treestore;
// and is a protected member of the MyTreeView class.
////
treestore->erase(iter);
break;
}
}
}
When execution gets to the point of failure (the erase statement), the
iter is in fact valid and is at correct row. I can print out information
stored on that row, this is why I'm certain. Execution does not get
beyond that line.
I've looked around for row removal examples, and had no luck. Anyone
here have any pointers?
Looping through a TreeModel and deleting things as you do above is very
liable to lead you to segfaults or unusual behaviour, as once you've
deleted the row indicated by iter, iter is no longer valid so you cannot
perform iter++ on it to move to the next row. This is a familiar
situation from using STL containers as well.
So while this might seem the most elegant solution, it unfortunately
isn't. You could try using Gtk::TreeModel::foreach using a suitable
callback function to check the values and delete rows appropriately, but
I'm not actually sure if that would be any more successful, as it
depends entirely on how foreach is implemented. Therefore I would
suggest that you have to do this in two stages.
1) use a for loop or a foreach() callback to run through the TreeModel
and build up a list, slist, vector or some other suitable container of
TreePaths or TreeIters which match the criteria for deletion
2) loop through that structure BACKWARDS and delete each Path or Iter
individually, so that you start at the end of the TreeModel and move
towards the front. This is necessary in order to avoid invalidating
paths pointing ahead of the position you just erased. For Iterators you
may actually be okay going forwards, I'm not sure. Try it and see; I
suggest Paths largely because my most recent example of doing something
like this was when I needed to delete all the selected rows in a
multi-select TreeView, which you get as an ArrayHandle<TreePath>. Iters
may keep track of their elements if you delete an element before them,
but Paths certainly won't. So going backwards is safest.
Hopefully that will prove of some assistance.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]