PDA

View Full Version : Context Menu event with QGraphicsWidget



onurozcelik
10th June 2010, 10:12
In my application I subclass QGraphicsWidget
In paint I am drawing a line with pen width 4.
I reimplemented boundingRect() and shape().
But I can't catch context menu event every time I click right mouse button.
What is the problem.(Pen Width ? )


//Sample code for boundingRect() and shape()

QRectF boundingRect() const
{
qreal rectLeft = x1 < x2 ? x1 : x2;
qreal rectTop = y1 < y2 ? y1 : y2;
qreal rectWidth = (x1 - x2) != 0 ? abs(x1-x2) : 4;
qreal rectHeight = (y1 - y2) != 0 ? abs(y1 -y2) : 4;

return QRectF(rectLeft,rectTop,rectWidth,rectHeigt);
}

QPainterPath shape()
{
QPainterPath path;
path.addRect(boundingRect());
return path;
}

high_flyer
10th June 2010, 11:07
But I can't catch context menu event every time I click right mouse button.
What is the problem.
you have to implement QGraphicsItem::contextMenuEvent()

onurozcelik
10th June 2010, 11:57
I have already reimplemented QGraphicsItem::contextMenuEvent()
But sometimes event works sometimes does not.
Could it be related with pen?

high_flyer
10th June 2010, 12:28
I don't think so, why do you think it could be related to the pen?
Can you show your implementation of contectMenuEvent()?

onurozcelik
10th June 2010, 13:05
Here is my *.cpp file contents


#include "blocksegmentitem.h"

BlockSegmentItem::BlockSegmentItem(QString id,int _x1,int _y1, int _x2,int _y2
,FieldItemLabel _label,QString _signalization):FieldItem(id,FieldProperty::BLOCKS EGMENTITEM)
{
x1 = _x1;
y1 = _y1;
x2 = _x2;
y2 = _y2;
label = _label;
signalization = _signalization;
createActions();
createContextMenu();
}

BlockSegmentItem::~BlockSegmentItem()
{

}

QRectF BlockSegmentItem::boundingRect() const
{
int rectLeft = x1 < x2 ? x1 : x2;
int rectTop = y1 < y2 ? y1 : y2;
return QRectF(QPointF(rectLeft,rectTop),sizeHint(Qt::Pref erredSize,QSizeF(-1,-1))).adjusted(-2,-2,0,0);
}

void BlockSegmentItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);

painter->setRenderHint(QPainter::Antialiasing);

if(signalization == "NO")
{
//Custom pen with width = 3
painter->setPen(dashedLinePen);
painter->drawLine(x1,y1,x2,y2);
}
else
{
//Custom pen with width = 4
painter->setPen(solidLinePen);
painter->drawLine(x1,y1,x2,y2);
}

if(label.visible)
{
if(label.rotateAngle != 0)
{
painter->drawText(label.x,label.y,label.text);
}
else
{
painter->drawText(label.x,label.y,label.text);
}
}
}


QSizeF BlockSegmentItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
{
Q_UNUSED(which);
Q_UNUSED(constraint);
return QSizeF(abs(x2-x1), abs(y2-y1) > 0 ? abs(y2-y1) : 4);
}

QPointF BlockSegmentItem::pos() const
{
return QPointF(x1,y1);
}

void BlockSegmentItem::contextMenuEvent(QGraphicsSceneC ontextMenuEvent *event)
{
contextMenu->exec(event->screenPos());
}

QPainterPath BlockSegmentItem::shape() const
{
QPainterPath path;
path.moveTo(x1,y1);
path.lineTo(x2,y2);
return path;
}

void BlockSegmentItem::changeLabelVisibility(bool visible)
{
label.visible = visible;
}

void BlockSegmentItem::createContextMenu()
{
contextMenu = new QMenu("BlockContextMenu");
contextMenu->addAction(blockProtectionAction);
}

void BlockSegmentItem::createActions()
{
blockProtectionAction = new QAction("Blogu korumaya al",this);
connect(blockProtectionAction,SIGNAL(triggered()), this,SLOT(blockProtectionRequested()));
}

void BlockSegmentItem::blockProtectionRequested()
{
qDebug()<<"Block Protection requested on: "<<getId();
}

I think it could be related to pen because I am painting a line in paint method. Naturally pen is very thin element and context menu event only occurs when I click a point on line.
Am I right? If I am right how can I do a better hit test.