PDA

View Full Version : Track first and last QListWidget items - Any ideas?



slscripters
26th April 2010, 11:11
Hi,

Another newbie query. :o

I've created a customized QListWidget with customized QListWidgetItem(s). I've followed some examples from here(forum). I've used the QAbstractItemDelegate to draw my customized list items.

Does anybody have any idea on how to track the first and last items in my list widget? I've restricted my listwidget only to display 5 items and disabled the scrollbars. My reason for tracking this is that I want to do some important drawing on every first and last item in my listwidget.

For example, I want my first and last list items to be bigger than the items between them. If I can track these items then I could somehow put these data using "setData" and retrieve these when drawing these items at "paint" function. In paint function I can then draw the appropriate size for each item. Thanks. :)

wysota
26th April 2010, 13:07
What do you exactly mean by "tracking" and "first" and "last"? You mean the first item that gets displayed (not the first item in the list) at the moment? If so, then it is possible to fiind out which item is the first and the last displayed, but once you start changing the data you will cause the list layout to be recalculated which can effectively change the first and last displayed item making you fall into infinite loop. In my opinion what you actually want is a custom list widget. You'd have to reimplement indexAt() and visualRect() for this to work.

nish
26th April 2010, 13:41
if i understood your problem correctly.. what you need is to reimplement QItemDelegate::sizeHint, in your delegate, and there you can return a different size for each item.

slscripters
26th April 2010, 14:21
Guys,

Thanks in advance. I apologize for posting an incomplete and unclear question. :o

What I mean of "Track first and last" items is that I need to know what are the first and last items displayed in the QListWidget item's viewport. Since I've restricted my list to only view 5 items at a time then item 0 is the first item and item 4 is the last item at first load of the QListItemWidget. Moving down by clicking, or by pressing down arrow until item 5 gets highlighted will make item 1 first and item 5 last.

@wysota I guess you understood my problem. :)

But I can't get a nice grasp about what you mean by "but once you start changing the data you will cause the list layout to be recalculated which can effectively change the first and last displayed item making you fall into infinite loop". My list widget actually is a plain QListWidget but its list items are customized? Is this method not enough?

The list items are implemented by subclassing QAbstractItemDelegate and overriding the paint method. In the paint method, I've specifiied how to draw a list item. But then from there I don't know if the current item drawn is the first or last item displayed - my problem. :(

@MrDeath
What if I want to do something aside from increasing the size of the items? I want to do some specific drawing on the first and last items displayed if possible.

Thank you very much for your help. :)

wysota
26th April 2010, 14:40
But I can't get a nice grasp about what you mean by "but once you start changing the data you will cause the list layout to be recalculated which can effectively change the first and last displayed item making you fall into infinite loop". My list widget actually is a plain QListWidget but its list items are customized? Is this method not enough?

Let's see what happens if you start scrolling your list. Item "4" becomes item "3" and item "5" becomes item "4". Thus the size of (new) item "3" needs to be decreased and size of (new) item "4" needs to be increased. Unfortunately it's hard to do it atomically (at least with QListWidget) so when you change the size of item "3", the last visible item will be (new) item "5" and not item "4", so you will try to increase the size of item "5" which will not fit into the screen and you will have to decrease it and increase the previous item and.... well... sounds complicated, right?



The list items are implemented by subclassing QAbstractItemDelegate and overriding the paint method. In the paint method, I've specifiied how to draw a list item. But then from there I don't know if the current item drawn is the first or last item displayed - my problem. :(

Don't confuse the item class and the delegate class.

What I said you needed to do is to tell your view that the first visible item and the last visible item should always be larger than the remaining items. Then you don't need to touch the delegate or anything else, reimplementing visualRect() should be enough.

slscripters
26th April 2010, 16:14
@wysota

Thanks again, I understand what you mean. Sorry I'll make my problem much clearer again...

Increasing the size of the first and last item was a very bad example, it introduces a complex situation. Like the one you have described.

Another example I think would be most appropriate is changing the color of the first and last item displayed in my list widget. How should I know these are the first and last item in my list widget so that I can modify their colors in the paint function? Or is there any other way to do this?

Thanks for your patience....:o

wysota
26th April 2010, 17:34
You can use indexAt() (or itemAt) to query for the item in position close to (0,0) for the first item and close to the maximum height for the last item visible.

slscripters
27th April 2010, 05:56
Hi, can please specify how to achieve this? I only know indexAt or itemAt will get the item at a certain index. But how can I use these functions to determine the first and last item? I guess you have already implicitly said your algorithm but I could not get it. Thanks :)

slscripters
27th April 2010, 07:37
@wsota

I thought indexAt or itemAt gets the item at a specified index. It uses QPoint by the way. I now understand your idea. Thanks very much, will try this! ;)

slscripters
28th April 2010, 11:37
Thank you very much it worked! ;)