I need some help understanding how QGraphicsItem::zValue() works in relationship to clipping. I have a scene with many text labels (QGraphicsSimpleTextItem-based). Because some sections of the scene can have many labels, it is possible for the labels to overlap. I am using QGraphicsItem::setZValue() to put a z-ordering on the labels, with more "important" labels having higher z values. All of the labels are siblings and children of a single parent QGraphicsItem. The labels can't be opaque; the scene information "behind" the labels has to show through.
I am having several problems:
- all of the items are painted, no matter what their z-value, so the result is a mess of overlapped labels.
- if I set QGraphicsItem::ItemClipsToShape for the labels, none of them are drawn, even ones that don't overlap
- if I call QGraphicsItem::collidingItems( Qt::IntersectsItemBoundingRect ) on any one of them, I get a list that contains only the parent or other non-label items in the scene.
If I try with this code ("textItems" is a std::vector<> that contains all of the siblings with the QGraphicsSimpleTextItem::Type ):
while ( it != eIt )
{
if ( pItem->isVisible() )
{
while ( oIt != eIt )
{
if ( pItem->collidesWithItem( pOther, Qt::IntersectsItemBoundingRect ) )
{
if ( pItem->zValue() < pOther->zValue() )
{
pItem->setVisible( false );
break;
}
else
pOther->setVisible( false );
}
}
}
}
std::vector< QGraphicsItem * >::iterator it = textItems.begin();
std::vector< QGraphicsItem * >::iterator eIt = textItems.end();
while ( it != eIt )
{
QGraphicsItem * pItem = *it++;
if ( pItem->isVisible() )
{
std::vector< QGraphicsItem * >::iterator oIt = it;
while ( oIt != eIt )
{
QGraphicsItem * pOther = *oIt++;
if ( pItem->collidesWithItem( pOther, Qt::IntersectsItemBoundingRect ) )
{
if ( pItem->zValue() < pOther->zValue() )
{
pItem->setVisible( false );
break;
}
else
pOther->setVisible( false );
}
}
}
}
To copy to clipboard, switch view to plain text mode
then the collidesWithItem does return true for many labels, but I still end up with overlaps in some places anyway, and this code is very, very slow since there are thousands of labels. It gets executed with every scene transformation (for example, zooming or panning).
Is there some way of getting QGraphicsScene / QGraphicsView to do this clipping automatically?
Bookmarks