Thanks to anda_skoa, I finally find a way to do it.
I don't think it's the best way but it works.
For those having the same issue here is what I did:
I changed my menu buttons from QPushButton to QGraphicsObject. In my buttons constructor, I set setAcceptHoverEvents(true) to be able to change button color when mouse hover them (I check in the paint() if option.state has the QStyle::State_MouseOver flag on and change Brush if it has).
I also set the flag ItemIgnoresTransformation because I don't want my buttons to be zoomed in or move when the scene is transformed (but still I can move then programmatically if I want to position them somewhere else on my scene).
Then I defined boundingRect(), paint() and mousePressEvent(). mousePressEvent accept the event (e->accept()) and emit a signal in my case, because I want to connect my button to slots (which is why I subclassed a QGraphicsObject and not a QGraphicsItem. It's not as good performance wise, but I have a small scene, so it should be fine).
Then I created a container for these buttons. This class subclass QObject (I wanted some signals/slots here too) AND QGraphicsItemGroup.
In this constructor I set setHandlesChildEvents(false) because this is just a container, and I want my buttons inside to receive the actual event.
Finally in my scene, I create a new container, add it to the scene, and created+added buttons in the container. Then I overloaded mousePressEvent in my scene to detect if a click happened on a QGraphicsItem or not. If it's not the case, I accept the event to avoid propagation to other widget, and I do what I have to do when a click on my scene happen.
If a QGraphicsItem has been clicked, then I just call the QGraphicsScene::mousePressEvent to propagate the events to children (then my container will ignore it because I asked him not to handle child events, and finally the buttons will accept it and react by emit a signal).
Here is my customScene::mousePressEvent (it's probably not the best way to implement it, so if anyone has some suggestions to improve it, I'll take'em !!!
):
{
if (event->button() == Qt::LeftButton)
{
QGraphicsItem* item
= this
->itemAt
(event
->scenePos
(), QTransform
());
if (!item)
{
// No graphics item has been clicked. The scene handle the event then.
event->accept();
// Move probes center
this->centerCrosshair->setPos(event->scenePos());
this->centerCrosshair->show();
// Move menu
this->menu->setMenuCenter(event->scenePos().x(), event->scenePos().y());
this->menu->show();
// Move pattern
for (int i = 0; i < this->pat.size(); ++i)
{
this->pat[i]->setCenter(event->scenePos().x(), event->scenePos().y());
}
}
}
}
void customScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
QGraphicsItem* item = this->itemAt(event->scenePos(), QTransform());
if (!item)
{
// No graphics item has been clicked. The scene handle the event then.
event->accept();
// Move probes center
this->centerCrosshair->setPos(event->scenePos());
this->centerCrosshair->show();
// Move menu
this->menu->setMenuCenter(event->scenePos().x(), event->scenePos().y());
this->menu->show();
// Move pattern
for (int i = 0; i < this->pat.size(); ++i)
{
this->pat[i]->setCenter(event->scenePos().x(), event->scenePos().y());
}
}
}
QGraphicsScene::mousePressEvent(event);
}
To copy to clipboard, switch view to plain text mode
I hope this could help some people trying to do the same thing. I spent a couple of days trying to figure this out. Now I read it, it seems trivial, but when you don't know, it's not.
If anyone has comments or suggestions to improve it, I'd be happy to ear them.
Thank you.
Bookmarks