PDA

View Full Version : How to create filter effect on QTreeWidget



harpo
27th February 2006, 09:47
Hi all,

Newbie here, I have created a QTreeWidget for displaying a list of records but I need to implement a filter functionality that allows the user to view only the records that fit the filter requirements.

E.g. would be I have records with the following columns, (Cateogry, Record Name, TimeStamp, Description, RecordID)

I would like to allow the user to filter according to the timestamp or cateogry and record name.

Currently, my implementation is that I will hide all items and then use QTreeWidget's findItems to show the items that fit the criteria. This is inefficient and I hope to get your opinions on this.

THanx for the help.
Harpo

zlatko
27th February 2006, 10:31
This is inefficient and I hope to get your opinions on this.
Sorry but why do you think that its inefficient solution?:rolleyes:

harpo
27th February 2006, 11:30
Hi, cause I will be dealing with big number of items and to run thru all the items to find the set would be time-consuming. Also, I have a few filters to implement at the same time, so I was hoping to find a way where I can bunch up that list for showing and then hide the rest at 1 shot.

wysota
27th February 2006, 11:30
If you switch from item based to model based approach, you'll be able to use the QSortFilterProxyModel.

harpo
27th February 2006, 11:31
thanks I will try that out.

jpn
28th February 2006, 09:49
Currently, my implementation is that I will hide all items and then use QTreeWidget's findItems to show the items that fit the criteria. This is inefficient and I hope to get your opinions on this.

By this way, you'll end up iterating through all items twice and the shown items even tree times. First you hide all items (1), then you call QTreeWidget::findItems which does internally (depending on the flags) iterate through all items (2) and then you once again iterate through returned items (3) to shown them.

A straightforward way to optimize this time-consuming task could be to implement a single loop where you match each item against all the filters and show/hide it according to the match result. Iterating through the items in a QTreeWidget should not be too expensive, as it's internal implementation seems to use a QList, which allows instantaneous index-based access.

Another 'optimizing trick' could be hiding the whole QTreeWidget during the update and then showing it again afterwards. This avoids you from causing numerous update events during the show/hide -loop.



If you switch from item based to model based approach, you'll be able to use the QSortFilterProxyModel.

This is definately the efficient way to go. I just wanted to throw you some ideas you could try out with less effort before switching to model based approach...

barnabyr
4th March 2006, 20:16
This is definately the efficient way to go. I just wanted to throw you some ideas you could try out with less effort before switching to model based approach...

Is it really though ? Before I found QSqlRelationalTableModel / QSqlTableModel which has its own very fast sort function I used a QSqlQueryModel with a sorting proxy. On a result set of 15,000 rows the sorting performance was completely unusable for a sort function that was just a simple a 'greater than' b thing.

Admittedly it was Qt4.0 when it was called something else like QProxyModel or something so maybe things have improved but it was enough to convince me that I shouldn't use it.

jpn
4th March 2006, 20:28
Well, my point was that compared to item based approach, such filtering in model based approach is way more efficient.
Not that I claim it to solve any efficiency problems on the earth.. ;)

wysota
4th March 2006, 21:38
The problem with sorting on SQL level is that if you do sorting/filtering there, you get completely different models, so all your indices get screwed (including persistent ones).
And you can't use it if you have more than one view displaying the same model and you want those views to have different sortings (unless all of them provide sorting on the view level (which they don't) which would leave you "comparing if a > b" anyway) or filters.

You say SQL sorting is much faster. Ok, but I bet you are working on a local dbms. Try to refetch several thousand records from a distant database, we'll see if it's faster than sorting on a proxy level ;)

barnabyr
5th March 2006, 04:31
The problem with sorting on SQL level is that if you do sorting/filtering there, you get completely different models, so all your indices get screwed (including persistent ones).
And you can't use it if you have more than one view displaying the same model and you want those views to have different sortings (unless all of them provide sorting on the view level (which they don't) which would leave you "comparing if a > b" anyway) or filters.

You say SQL sorting is much faster. Ok, but I bet you are working on a local dbms. Try to refetch several thousand records from a distant database, we'll see if it's faster than sorting on a proxy level ;)

You are right the db is on our LAN. But the performance was so quick I thought it was sorting cached data in the model. I didn't figure when you call a sort that it would regenerate the query. I suppose I could run some tests because I generate temporary table to fill the model. If I delete the table and close the connection after reading it before I sort I could tell if the data was cached or not.