You are not logged in.

1

Friday, March 2nd 2012, 11:11am

QGraphicsItem : mousePressEvent not called

Hi,

I would like to reimplement mouseEvent methods in my customized QGraphicsItem (for example in Ellipse, inherited from QGraphicsEllipseItem).

Firstly, in my View, i reimplemente the mousePressEvent method :

Source code

1
2
3
4
5
6
7
8
9
void View::mousePressEvent(QMouseEvent *mouseEvent)
{
  qDebug() << "vue mouse press event";

  this->getScene()->addItem(this->getScene()->getBuilder->createItem(mouseEvent->pos()));
  this->getScene()->update();

  QGraphicsView::mousePressEvent(mouseEvent);
}


The QGraphicsView mousePressEvent enables me to send the event to my scene. In my scene, i have :

Source code

1
2
3
4
5
6
void Scene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
  qDebug() << "scene mouse press event";

  QGraphicsScene::mousePressEvent(mouseEvent);
}


This is works and i have the qDebug() which are displayed (qDebug() of the view before the qDebug() of the scene.. it seems normal).

But, whith my ellipse item, the mousePressEvent is not called. Here is my ellipse item :

Source code

1
2
3
4
5
6
7
8
TEllipse::TEllipse(QGraphicsItem *parent, QGraphicsScene *scene, QPoint center, int radius) : QGraphicsEllipseItem(parent, scene)
{
  this->center = center;
  this->radius = radius;
  this->setFlag(QGraphicsItem::ItemIsSelectable);
  this->setAcceptHoverEvents(true);
  this->setAcceptedMouseButtons(Qt::LeftButton);
}


Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
void TEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
  const QPoint c = center;
  painter->drawEllipse(c, this->radius, this->radius);
}

QRectF TEllipse::boundingRect()
{
  QPointF topLeft(this->center.x()-this->radius, this->center.y()-this->radius);
  QPointF bottomRight(this->center.x()+this->radius, this->center.y()+this->radius);

  return QRectF(topLeft, bottomRight);
}


Source code

1
2
3
4
5
6
7
8
9
10
void TEllipse::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
  qDebug() << "mouseEvent is accepted ? " << mouseEvent->isAccepted();

  mouseEvent->accept();

  QGraphicsEllipseItem::mousePressEvent(mouseEvent);

  qDebug() << "ELLIPSE MOUSE EVENT";
}


But when i click in my view, after the qDebug() of my view and my scene, nothing is displayed :s I don't understand why.

Also, I tried to reimplement shape in my item :

Source code

1
2
3
4
5
6
7
QPainterPath TEllipse::shape() const
{
  QPainterPath path;
  path.addRect(this->rect());

  return path;
}


But the same result.

Any ideas ?

Thank you a lot :-)

EDIT : Apparently, when i create an Ellipse item in my scene constructor, the qDebug() "sceneEvent" for the sceneEvent method reimplemented in Ellipse class is displayed.

So i can perahps get from it the mousePressEvent...

Nevertheless, when i tried to click on it after the creation, the sceneEvent doesn't appeared anymore :s

But when i only click in the view and the mousePressEvent of my view is called (creation through my builder class of the ellipse item which is added to the scene), the sceneEvent is not called.

So, i have two questions :

- Why i need to use the sceneEvent to get the mousePressEvent ? Why the mousePressEvent of my ellipse item is not automatically called by my scene ?

- Why when i only click in my view, the sceneEvent doesn't appeared ?

Thank you :-)

This post has been edited 2 times, last edit by "msarc" (Mar 2nd 2012, 11:42am)


2

Friday, March 2nd 2012, 12:43pm

have you tried replacing your versions of the scene and view with the default QGraphicsScene/QGraphicsView version - it might be that the scene is responsible for passing mouse events on to items.
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

3

Friday, March 2nd 2012, 1:01pm

Thank you Amleto for your answer :-)

Ok i have tried to do that :

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
TArea::TArea(QWidget *parent) : QWidget(parent)
{
  QHBoxLayout *areaLayout = new QHBoxLayout(this);
  this->setLayout(areaLayout);

  
  view = new QGraphicsView(this);
  view->setFixedSize(700, 400);
  
  QGraphicsScene *scenet = new QGraphicsScene();

  
  TEllipse *item = new TEllipse(0, scenet, QPoint(20,20), 50);
  scenet->addItem(item);

  
  view->setScene(scenet);
  view->setMouseTracking(true);
  areaLayout->addWidget(view);
  view->show();

//  view = new View(this);
//  areaLayout->addWidget(view);
//  view->show();
}


with always my ellipse class which contains the reimplemented mousePressEvent with a qDebug() but nothing appeared for the moment :s

Juste the sceneEvent() the first time i draw the ellipse but only the first time (when i click on it after, the sceneEvent qDebug is not displayed).

It's very weird :s

EDIT :

I have done a new project with simply :

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Widget::Widget(QWidget *parent) : QWidget(parent)
{
    QGraphicsView *vue = new QGraphicsView(this);
    vue->setMouseTracking(true);
    vue->setFixedSize(800, 400);

    QGraphicsScene *scene = new QGraphicsScene();
    Ellipse *ellipse = new Ellipse(0, 0, 50, 50, 0, scene);
    scene->addItem(ellipse);

    vue->setScene(scene);

    vue->show();
}


and :

Source code

1
2
3
4
5
6
7
8
9
10
Ellipse::Ellipse(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsEllipseItem(x, y, w, h, parent, scene)
{
    this->setFlag(QGraphicsItem::ItemIsSelectable);
}

void Ellipse::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    this->setScale(5);
    this->prepareGeometryChange();
}


the scale works so the mousepressEvent of my item is called..

But i don't understand why is not the same thing in my project :s

EDIT : I think i have found the problem but i don't understand how i can solve it and why it works like it.

If i replace my ellipse constructor from :

Source code

1
2
3
Ellipse::Ellipse(qreal x, qreal y, qreal w, qreal h, QGraphicsItem 
*parent, QGraphicsScene *scene) : QGraphicsEllipseItem(x, y, w, h, 
parent, scene)


to :

Source code

1
2
Ellipse::Ellipse(qreal x, qreal y, qreal w, qreal h, QGraphicsItem 
*parent, QGraphicsScene *scene) : QGraphicsEllipseItem(parent, scene)


by painting my own item with the virtual method paint (and boundingRect) :

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void testEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->drawEllipse(QPoint(10,10), 50, 50);
}

QRectF testEllipse::boundingRect ()const
{
    qDebug() << "le rect : " << this->rect();

  QPointF topLeft(-40, -40);
  QPointF bottomRight(60, 60);

  return QRectF(topLeft, bottomRight);
}


The mousePressEvent is not called anymore ...

Any ideas ?

This post has been edited 2 times, last edit by "msarc" (Mar 2nd 2012, 2:10pm)


4

Friday, March 2nd 2012, 6:29pm

But graphics Items should not have scene as a parent - your ellipse (and the sub class) should be top level graphics item - no parent. That could well be throing things awry.


You could also maybe try some of these (or get rid of the methods) -I dont think you need to write your won code for these methods:

Source code

1
2
3
4
5
6
7
8
9
void testEllipse::paint(...)
{
  QGraphicsEllipseItem::paint(...);
}

QRectF testEllipse::boundingRect () const
{
  return QGraphicsEllipseItem::boundingRect();
}
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.