PDA

View Full Version : Applying treatment after screen rendering on specific items with QGraphicsView



scascio
30th September 2009, 10:01
Dear Qt workers,

I am using custom items to display images, polygons and labels in a QGraphicsView.

Going further on QGraphicsItem features, I want to apply a treatment on the result of the images rendered on the screen. The treatment applies only on image data and not labels, neither polygons.

So I wondering myself what is the best way to manage an off screen buffer, apply treatments, then display it :
1 - manage a group item that will be updated with images displayed, and play with paintEvent. Since paintEvent of children will be called before the group item, I can fill an off screen buffer, then apply the treatments in the paintEvent of the group
2 - overload the [QTCLASS]QGraphicsScene::drawItemsQTCLASS] to first draw raw data of image items, then apply treatments. Polygons and labels can be painted then without interferring.

Maybe there is another features of QGraphicsView I didn't see.
Does anyone had the same needs, and how did you do it?

Thanks by advance.

wysota
30th September 2009, 10:55
What kind of treatments are we talking about? If you can afford using unstable code, look into Qt 4.6 and the effect classes for graphics items.

scascio
30th September 2009, 11:12
The treatment involved is histogram stretching, that apply on pixels rendered.
So I need to compute the histogram of the screen (but without labels and polygons), then stretch it.

My problem is that the treatment relies on images displayed and is not independant for each item.

Anyway, QGraphicsEffect in 4.6 seems awesome! Thanks.

wysota
30th September 2009, 11:47
The simplest way is to reimplement paint() for all items you want to control and adjusting the colours there. A better way would be to do it once - when each item is created - but it's a bit more work.

scascio
30th September 2009, 13:41
I am sorry but I can't see your thought.

How can I get the display result of items painted, then modifiy the result of the paint event with some parameters that depends on the set of items painted?

If I move or zoom, the set of items changes, so the treatement is different.

wysota
30th September 2009, 14:26
Reimplement QGraphicsView::drawItems() and do your calculations there.

scascio
30th September 2009, 14:48
Thanks for confirming.

scascio
1st October 2009, 10:04
Overloading QGraphicsView::drawItems is exactly where I need to do my specific computation.

So I can call myself the paint of each items with something like I found in the docs and in some QGraphicsScene implementation from koders site at http://www.koders.com/cpp/fidF0D7D36ED38A954D392342ADD614BC92ACCADD30.aspx?s =sceneMatrix#L948 :

void QMyGraphicsView:drawItems(QPainter * painter, int numItems, QGraphicsItem * items[], const QStyleOptionGraphicsItem options[]) {

for(int i=0;i<numItems;i++) {
painter->save();
painter->setMatrix(items[i]->sceneMatrix(), true);
items[i]->paint(painter, &options[i], this);
painter->restore();
}
}

But I encountered some disagreements. It seems that the default implementation of drawItems is more complicated than that :
* The items with flag QGraphicsItem::ItemIgnoresTransformations are not rendered properly with the loop I wrote
* The items cached with QGraphicsItem::DeviceCoordinateCache are painted for each call of drawItems, while the default drawItems save a lot of paintings.

Does anyone knows where I can find the real default implementation of QGraphicsScene::drawItems according to item flags?

I will investigation myself on changing my design to do my computation and set attributes of the item of my scene, then call the default drawItems.

wysota
1st October 2009, 10:07
Sure it is more complicated. According to me you should only do some calculations of yours there, optionally modify the options and then call the base class implementation from QGraphicsView. The rest has to be done from within the items' paint() routine. Of course be aware that you will probably ruin cached items anyway.