PDA

View Full Version : Context Menu & QGraphicsWidget



onurozcelik
11th May 2010, 09:04
Hi,
In my application I have two object type. One is field item, other is composite item.
Composite items may contain two or more field items.
Here is my composite item implementation.


#include "compositeitem.h"

CompositeItem::CompositeItem(QString id,QList<FieldItem *> _children)
{
children = _children;
}

CompositeItem::~CompositeItem()
{
}

QRectF CompositeItem::boundingRect() const
{
//Not carefully thinked about it
return QRectF(QPointF(-50,-150),QSizeF(250,250));
}

void CompositeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
{
FieldItem *child;
foreach(child,children)
{
child->paint(painter,option,widget);
}
}

QSizeF CompositeItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
{
QSizeF itsSize(0,0);
FieldItem *child;
foreach(child,children)
{
// if its size empty set first child size to itsSize
if(itsSize.isEmpty())
itsSize = child->sizeHint(Qt::PreferredSize);
else
{
QSizeF childSize = child->sizeHint(Qt::PreferredSize);
if(itsSize.width() < childSize.width())
itsSize.setWidth(childSize.width());
itsSize.setHeight(itsSize.height() + childSize.height());
}
}
return itsSize;
}

void CompositeItem::contextMenuEvent(QGraphicsSceneCont extMenuEvent *event)
{
qDebug()<<"Test";
}

My first question is how I can propagate context menu event to specific child.

4610

Picture on the above demonstrates one of my possible composite item.

If you look on the code above you will see that I print "Test" when context menu event occurs.

When I right click on the line symbol I see that "Test" message is printed.
But when I right click on the signal symbol "Test" is not printed and I want it to be printed.

My second question what cause this behaviour.
How do I overcome this.

totem
11th May 2010, 13:19
First of all concerning your composite item's ::boudingRect(), you really should "think about it" :) My guess is to merge every child item's bounding rect.

To ensure you computed the right boundingRect, add this code in your CompositeItem::paint() :



painter->save() ;
painter->setPen(Qt::yellow) ;
painter->setBrush(Qt::NoBrush) ;
painter->drawRect(boundinRect()) ;
painter->restore() ;


And try to right-click on your composite item, maybe it will suffice (didn't try so I'm not sure)

onurozcelik
12th May 2010, 08:53
You are right buddy. I think seriously about boundingRect.:) (I edited the code)


QRectF CompositeItem::boundingRect() const
{
FieldItem *child;
QRectF rect(0,0,0,0);
foreach(child,children)
{
rect = rect.united(child->boundingRect());
}
return rect;
}

I thinks its is a neat idea to unite child items boundingRects but this time
item can' t catch events like contextmenuevent, mousepressevent.
I tried to click everywhere inside boundingRect.
What may cause this?

totem
12th May 2010, 10:56
sorry, I've no idea without seeing involved source code. It might come from an event you accept too early in the scene or not forwarded by a virtual method call, or even items are not selectable, etc.

onurozcelik
12th May 2010, 12:08
I solved the problem temporarily. I rewrite paint. Now it looks as follows.


void CompositeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
{
painter->setPen(Qt::transparent);
painter->drawRect(boundingRect());

FieldItem *child;
foreach(child,children)
{
child->paint(painter,option,widget);
}
}

Now I can catch events occurs inside rectangle;)