PDA

View Full Version : Filtering a TreeWidget



soul_rebel
17th January 2008, 23:48
I have tree widget and i want to filter, a certain kind of child

I wrote the following slot that gets triggered whenever the contents of the lineedit eBrowseFilter changes:


void QMyClass::refilterBrowseTree()
{
bool hide = true;
QTreeWidgetItem *c = 0;

QObjectList children = browseTree->children();
browseTree->setUpdatesEnabled(false);
for (int i = 0; i < children.count(); ++i)
{
c = (QTreeWidgetItem*)children.at(i);

hide = false;
if (c->type()==1000)
{
if (!c->text(0).contains(eBrowseFilter->text()))
hide = true;
}
c->setHidden(hide);
}
browseTree->setUpdatesEnabled(true);
browseTree->update();
}
The Program segfaults as soon as I enter something into eBrowseFilter... The Backtrace tells me it actually failed in QTreeWidget::setItemHidden()...
How can that be? Whats wrong?

Thanks for your help!

Disclaimer:
I know Qt4 has this great model-view-thing, but I personally think it rather inconvenient, since QTreeWidget doesnt allow me to setModel (its private), and reimplementing all the Item-based features for QTreeView looks like a lot of work (after all I am really happy with QTreeWidget, i just want to do some filtering).

wysota
18th January 2008, 00:37
The Program segfaults as soon as I enter something into eBrowseFilter... The Backtrace tells me it actually failed in QTreeWidget::setItemHidden()...
How can that be? Whats wrong?

Tree widget items are not widgets nor even QObjects and you treat them as such thus casting objects from the list to QTreeWidgetItem gives you trash instead of objects you expect and your code goes into the bushes, as we say in Poland :)


Disclaimer:
I know Qt4 has this great model-view-thing, but I personally think it rather inconvenient, since QTreeWidget doesnt allow me to setModel (its private),
Because QTreeWidget is meant to hide the model-view architecture.


and reimplementing all the Item-based features for QTreeView looks like a lot of work (after all I am really happy with QTreeWidget, i just want to do some filtering).
Take a look at QStandardItemModel. It does more or less the same as convenience widgets.

I never had to reimplement QTreeView or any other view to make it do what QTreeWidget or family do out of the box. If you think you have to, then maybe you're just missing some feature in the model or in the view.

Disclaimer ;)
I don't say Item Views are perfect - they are not. But they are really nice to use in many cases.

luf
18th January 2008, 15:37
I would recommend same as wysota says. Model/view.

If you do that, you can use the Qsortproxyfiltermodel to filter /proxy on different views at the same time if needed as well. This make it easier to store loads of parameters not visible to the user, but needed in data structures, while you still can have some parameters visible to the user if you want. Also you can implement custom data/setdata functions on a proxy model, that makes it easier to edit the same data from different places or different widgets/input methods, while the original model keeps it's standard model...

That wasn't well written, but you get the point...

soul_rebel
25th January 2008, 18:11
Ok, I got it to filter like I want it to ( the Problem was - as Wysota pointed out - casting the children ):

void QMyClass::refilterBrowseTree()
{
bool hide = true;
QTreeWidgetItem *c = 0,
*cc = 0;
browseTree->setUpdatesEnabled(false);

for (int i = 0; i < browseTree->invisibleRootItem()->childCount(); ++i)
{
c = browseTree->invisibleRootItem()->child(i);

for (int ii = 0; ii < c->childCount(); ++ii)
{
cc = c->child(ii);
hide = false;
if (cc->type()==1000)
{
if ( !cc->text(0).contains(eBrowseFilter->text()) ) )
hide = true;
}
cc->setHidden(hide);
}
}
browseTree->setUpdatesEnabled(true);
browseTree->update();
}
The only problem is that it takes about 20seconds to do it (the UI hangs during that time). :(
There are about 17K items in the list, but filtering a treewidget in kde3/qt3 with klistviewsearchline didnt take any time (and klistviewsearchline iterates through the items as well if I understood it correctly)...

I had a closer look at Model/View-Programming and think it is really confusing. If you think there is no way around it I'll open a new thread and try to solve my problems with a new Model/View Thing, but if you have an idea how to to filter faster doing what I do right now, I would be happy!

Thanks!

wysota
25th January 2008, 19:01
Try to find the bottleneck using a profiler. There is no point in trying to optimize something if it is something else that greatly reduces the performance.

soul_rebel
26th January 2008, 19:00
Try to find the bottleneck using a profiler. There is no point in trying to optimize something if it is something else that greatly reduces the performance.
Well, unfortunately valgrind ist broken on FreeBSD right now, valgrind-devel works but crashes my application (which doesnt crash when being run alone).
Really weird and I know to little about Memory-Management-Internals to debug this.
I'll try to setup a Model-View for my data and ask in a new thread when I run into Problems.

wysota
26th January 2008, 20:08
Use gprof.