3

I have a custom QGraphicsView and a custom QGraphicsItem. I want the Item to handle my click if I click in the item, else I want the click to be handled by the View.

But when I click on the item, the item handles the click. This is ok. But if I click somewhere else the click isn't handled at all. All the code in my classes that have anything to do with mouseEvents is below.

class CustomView : public QGraphicsView
{
    Q_OBJECT

public:

    void mousePressEvent(QGraphicsSceneMouseEvent *event);

};

void CustomView::mousePressEvent(QGraphicsSceneMouseEvent *event){
    cout << "pressing in view";
}

class CustomItem : public QGraphicsItem
{
public:
    CustomItem(CustomView* widget)
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
};

CustomItem::CustomItem(CustomView* widget){
    setFlag(ItemIsSelectable);
    setFlag(ItemIsMovable);
}

void CustomItem::mousePressEvent(QGraphicsSceneMouseEvent *event){
    cout << "pressing in item";
}

It seems that when I remove the mousePressEvent function from the CustomItem class and change in the CustomView the mousePressEvent function to:

void CustomView::mousePressEvent(QMouseEvent *event){
    cout << "pressing in view";
}

the CustomView handles all the mouseEvents.

How can I let the CustomItem handles the clicks in the items and the CustomView handle all the other clicks?

Thank you.

EDIT

So now I have changed it to:

    class CustomView : public QGraphicsView
{
    Q_OBJECT

public:

};

 class CustomScene : public QGraphicsScene
{
protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
};


void CustomScene::mousePressEvent(QGraphicsSceneMouseEvent *event){
    cout << "pressing in scene";
}

class CustomItem : public QGraphicsItem
{
public:
    CustomItem(CustomView* widget)
protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
};

CustomItem::CustomItem(CustomView* widget){
    setFlag(ItemIsSelectable);
    setFlag(ItemIsMovable);
}

void CustomItem::mousePressEvent(QGraphicsSceneMouseEvent *event){
    cout << "pressing in item";
}

A Click in the scene but not in an item get handled by the scene. But clicks in the items dont get handled by the items itself, instead it get handled by the scene. Unless if you click 2 times really fast on the items it gets handled by the scene and the item.

Any ideas?

fibera
  • 495
  • 3
  • 8
  • 15
  • try overriding `QGraphicsScene::mousePressEvent ( QGraphicsSceneMouseEvent * mouseEvent )` method in QGraphicsScene, instead of QGraphicsView – Kunal Apr 10 '12 at 04:26
  • I think your "CustomWidget::mousePressEvent" is supposed to be "CustomView::mousePressEvent" (or vice versa). – Anthony Apr 10 '12 at 04:42
  • @Kunal Ty for your input, I moved the mousePressEvent to the scene but I still have a problem with it – fibera Apr 10 '12 at 17:22
  • @Anthony Yes indeed, I changed it in the code. Ty for noticing. – fibera Apr 10 '12 at 17:22

1 Answers1

5

QGraphicsView isn't really a good place to handle scene-specific events. Instead, you'll need to override QGraphicsScene::mousePressEvent. I would recommend something like this:

void CustomScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
  if (itemAt(event) == NULL)
  {
    // do stuff if not clicked on an item
  }
  else
  {
    QGraphicsScene::mousePressEvent(event); // this forwards the event to the item
  }
}

Note that QGraphicsScene::itemAt might give you difficulties if you have items with the ItemIgnoresTransformations flag set to true. Look to the docs for QGraphicsScene::itemAt for how to resolve this.

Anthony
  • 8,570
  • 3
  • 38
  • 46
  • Ok, so I removed the QGraphicsView::mousePressEvent(QGraphicsSceneMouseEvent) and added that function to the custom QGraphicsScene. Now if I click somewhere not on an item the scene handles my click. If I click on an item the scene also handles my click. But if I click 2 times very fast on the item, the item and the scene handle my click. – fibera Apr 10 '12 at 17:13
  • @fibera I realized a mistake I made in my answer. Try out the edited answer and let me know how it goes. – Anthony Apr 10 '12 at 17:32
  • @fibera No problem. I just remembered that QGraphicsView also has an itemAt method, so if you wanted, you could ditch the custom QGraphicsScene in favor of your custom QGraphicsView as you were originally trying. However, I still feel that scene-specific events should be handled by QGraphicsScene... it's up to you! – Anthony Apr 10 '12 at 18:05