Design question: Optimize item layout management in a QGraphicsScene
Hi,
I have a class with a QGraphicsView/QGraphicsScene (m_scene) and a QList (m_itemList) which holds all items of the scene. (The items content can be altered by the user which can modify the items bounding rect.) Because I want to layout the items dynamically I have a slot called updateItemLayout() which orders the items in a "line layout" with automatic line break to avoid showing the horizontal scrollbar. So far all is ok, but how to call the slot best?
- Connecting the changed() and sceneRectChanged() signal from the QGraphicsScene to my slot triggers the slot too often. E. g. the pure selection of an item triggers it, but the bounding rect of the item is not changed, so calling the layout-slot is not necessary.
- Give each item a pointer to the class so that the item can call the layout-slot when needed. Guess that that solution is bad code designing.
- Modify the items with signal, which are emited when the bounding rect changes. Problem: Items are not fix. User can add and delete items, so I need to add and delete connections quite often.
Is there any other possibility? Or which of the above is the best one?
Thanks,
Lykurg
P.s.: All items (e.g. TextItemText) are subclassed form pure virtual class "AbstractTextItem" which has QGraphicsItem as base.
Code:
void <class>::updateItemLayout()
{
qreal gWidth = 0, gHeight = 0, heightDiff = 0, itemWidth = 0, padding = 3;
TextItemText it;
it.setFont(m_fontGraphicsView);
qreal lineHeight = it.boundingRect().height() + 2;
for (int i = 0; i < m_itemList.size(); ++i)
{
AbstractTextItem* item = m_itemList.at(i);
heightDiff = (lineHeight - item->sceneBoundingRect().height()) / 2;
itemWidth = item->sceneBoundingRect().width();
if (gWidth != 0 && (gWidth+itemWidth+3*padding) > ui.view->width())
{
gHeight += lineHeight;
gWidth = 0;
}
item->setPos(gWidth, gHeight+heightDiff);
gWidth += itemWidth;
}
QRectF tmp
= m_scene
->itemsBoundingRect
();
tmp.moveLeft(-padding);
tmp.moveTop(-padding);
m_scene->setSceneRect(tmp);
}
Re: Design question: Optimize item layout management in a QGraphicsScene
Did you have a look at QGraphicsItem::itemChange ??
May be it will solve your purpose :)
Re: Design question: Optimize item layout management in a QGraphicsScene
Quote:
Originally Posted by
aamer4yu
Nice, I havn't seen this yet, but unfortunately GraphicsItemChange has no value ItemBoundingRectChange.
Meanwhile I have think of a other solution, which seem to fit best my purpose:
I subclass QGraphicsScene and put there my updateItemLayout() function. If an item changes it size (I will put a routine into my custom items) i call the function myself in the item via scene()->updateItemLayout().
Thanks for mentioning QGraphicsItem::itemChange
Lykurg
Re: Design question: Optimize item layout management in a QGraphicsScene
You can do this...
from QGraphicsItem::itemChange , emit a signal layoutChanged(this) . Catch this signal in the handling class.
from the graphicsItem pointer you can retrieve the bounding rectangle
Also see the various options that GraphicsItemChange has .