PDA

View Full Version : GraphicsItems: Mixing composition and custom painting



Asperamanca
20th April 2011, 12:53
Hi folks,

When I create my own GraphicsItems (or -Objects or -Widgets), the two main approaches would either be composition (i.e. I add sub-items and let my custom item act like a "Group of items"), or custom painting (i.e. I write my own paint routine, bounding rectangle and shape implementations).

Both have their advantages - of course, pure composition is much easier, as I do not have to worry about things like the BoundingRect or Shape, individual items within my "group" can be selected, and collision detection works.

Custom painting is much more powerful, and (if done right) can yield better performance (e.g. I do not clutter the Bsp tree with objects that do not need to be selected or moved around individually). I have much more control on what is done, and how much is done.

In some cases, mixing those two approaches sounds attractive: Custom paint those parts of a GraphicsItem that would be complex to compose, and that need not worry about things like selection or collision detection.
Compose those parts out of other GraphicsItems that require things like selection or collision detection.

What would I have to watch out for?

I assume one limitation is that the custom painting can only occur either as background or as foreground, since I need to call the QGraphicsItem::paint routine at some point, and it will paint all my "grouped" items according to z-order, in one go. I can either put my custom painting code before or after that (or both), but not in-between items.

What would I do about the boundingRect and shape methods? How would I include the boundingRect and shape info of my composite items into my own, custom paint boundingRect and shape info?

Any other pitfalls you see in that concept?

Edit: Removed unintentional smily

jano_alex_es
20th April 2011, 13:18
I don't understand why are you doing this.

If you need a GraphicsItem you can subclass the one than suits your needs (QGraphicsPixmapItem, QGraphicsRectItem...), if you need to add extra code to paint you can do it... or not. It's not something you must do.

On the other hand, if I want to have a object which groups QGraphicsItem I'd prefer to subclass QList or QHash. Why do you want to subclass a QGraphicsItem to have a group of items inside?

Asperamanca
20th April 2011, 13:30
I don't understand why are you doing this.
[...]
Why do you want to subclass a QGraphicsItem to have a group of items inside?

In short: To structure my code, and make it more reusable.

Consider a QGraphicsWidget that draws 2D-Curves.

6264

It has a rectangular shape, a background, a grid, multiple curves in different colors. I might wish to be able to select the single curves, but not the grid. The grid might even use paint code implemented elsewhere, because I need grids for other objects, too, and they should look the same.

This curve painting class should be a single object, so I can re-use it easily. Because I might want to be able to select the single curves, it would make sense that they are single GraphicsItems (e.g. Polylines). For the grid, that wouldn't make much sense, it's purely background, but it would span a significant portion of the Bsp tree and thus clutter it unnecessarily.

Does this example help to understand what I am driving at?

jano_alex_es
21st April 2011, 01:58
In my opinion:

Background: you have several options. For example create a QGraphicsPixmap item set as your own background. You can also have a image with only one grid and set it as "texturePattern" in a QBrush.
In my opinion the best option is to reimplement the method "drawBackground" and draw it manually there. You could add the needed extra code there as well.

Note some devices have cache problems with big QPixmap sizes. In many cases you could need to "divide" que pixmap in small pixmaps.

Curves:
I think you can solve your problem checking "QGraphicsPolygonItem" and "QGraphicsPathItem",and subclass one depending what you need.

Asperamanca
21st April 2011, 08:21
Background: you have several options. For example create a QGraphicsPixmap item set as your own background. You can also have a image with only one grid and set it as "texturePattern" in a QBrush.

I didn't think about using a QBrush as a texturePattern. It might not be the best solution here, but certainly one I might want to use elsewhere.

I also think my grid will change too often to make using a pixmap or texture worthwhile in this specific application.


In my opinion the best option is to reimplement the method "drawBackground" and draw it manually there. You could add the needed extra code there as well.

Sounded like a great idea, until I checked Qt help. drawBackground is only available for GraphicsView and GraphicsScene. What I want to develop is a GraphicsWidget, that can be part of a larger scene.
Still, useful to know whenever I need a specific background for a whole view or scene.


Note some devices have cache problems with big QPixmap sizes. In many cases you could need to "divide" que pixmap in small pixmaps.

drawPixmapFragments might be a solution, but I haven't explored it yet.
Fortunately, this is not one of the problems bugging me here.


Curves:
I think you can solve your problem checking "QGraphicsPolygonItem" and "QGraphicsPathItem",and subclass one depending what you need.

I'll use either QGraphicsPolygonItem or drawPolyine for sure.

Thanks for your views!