PDA

View Full Version : QAbstractItemView - visualRect never called, nothing painted



ghassett
18th April 2009, 20:29
Hi - I have subclassed QAbstractItemView, but my implementation of the visualRect() method never gets called (and nothing ever gets painted). To ensure that the model is not empty, I overrode the setRootIndex, and I simply output the number of items in the model after calling the base class's implementation.

So, when setRootIndex gets called, I see that my model contains 23 items. Here's the code that tells me so:


void GalleryView::setRootIndex (QModelIndex rootIndex)
{
QAbstractItemView::setRootIndex(rootIndex);

qDebug () << "there are" << model()->rowCount(rootIndex) << "items to view";
}


I do not understand why the base class (QAbstractItemView) does not begin calling my visualRect() function as it tries to lay out the 23 items in my model... any help would be appreciated! (Code attached)

// thanks // greg //

wysota
18th April 2009, 21:50
Most probably because you never call it while drawing (nor at any other meaningful at the moment point).

ghassett
18th April 2009, 21:59
I realize that I am not calling visualRect myself. I thought that the QAbstractItemView class would automatically call this method once it knew how many items to draw (through the contents of the model) and where the items were located (through the implemention of visualRect).

It would seem that QAbstractItemView, given the number of items in the model and the location of each item, could handle the entire she-bang of setting up and maintaining the scroll bars, viewport extents, the selection of items, keyboard handling, and calling my delegate's paint function with appropriate options (e.g., selected, focus, drawing rectangle) when it was time to actually draw the item.

The documentation says that QAbstractViewItem "provides standard support for keyboard and mouse navigation, viewport scrolling, item editing, and selections." It also says that "view classes that inherit QAbstractItemView only need to implement their own view-specific functionality, such as drawing items, returning the geometry of items, finding items, etc." This would imply to me that if I could draw items (via a delegate) and return (to QAbstractItemView's methods) the geometry of items, then QAbstractView would take care of the loops that iterate over the model calling my delegate to paint into the rectangles that I return via visualRect().

wysota
18th April 2009, 23:39
I realize that I am not calling visualRect myself. I thought that the QAbstractItemView class would automatically call this method once it knew how many items to draw (through the contents of the model) and where the items were located (through the implemention of visualRect).
Not really. That's what paintEvent is for.


It would seem that QAbstractItemView, given the number of items in the model and the location of each item, could handle the entire she-bang of setting up and maintaining the scroll bars, viewport extents, the selection of items, keyboard handling, and calling my delegate's paint function with appropriate options (e.g., selected, focus, drawing rectangle) when it was time to actually draw the item.
It inherits QAbstractScrollArea, not QScrollArea so it doesn't know how to handle the canvas. VisualRect() returns main (which doesn't have to be the only) rect occupied by an item but nobody says the view contains items only and no space around it.



The documentation says that QAbstractViewItem "provides standard support for keyboard and mouse navigation, viewport scrolling, item editing, and selections."
Yes, that's true. If you do rubber-band selecting in the view, indexAt() will be called and it will call visualRect().


It also says that "view classes that inherit QAbstractItemView only need to implement their own view-specific functionality, such as drawing items, returning the geometry of items, finding items, etc." This would imply to me that if I could draw items (via a delegate) and return (to QAbstractItemView's methods) the geometry of items, then QAbstractView would take care of the loops that iterate over the model calling my delegate to paint into the rectangles that I return via visualRect().

No, it means you have to implement the painting method which you didn't. Nobody said a view had to use delegates at all. Furthermore visualRect() might return an empty rectangle for an item but the item may still be visualized. The view provides an infrastructure, not a complete implementation. It's not an easy task to implement a view properly as many methods have to be reimplemented and they are quite prone to mistakes that are quite hard to debug.

ghassett
19th April 2009, 15:51
Just wanted to thank you guys for your helpful and accurate responses... I wrote all the painting code yesterday and everything works as advertised. Your explanations were very helpful and are very much appreciated!

- Greg