[Solved] QGraphicsItem::mouseReleaseEvent not called
-
It's explained in the "docs":http://developer.qt.nokia.com/doc/qt-4.7/qgraphicsscene.html#id-cf2e5af5-ab61-4db6-be20-b8d3d152f5eb.
-
Also in the QGraphicsItem "docs.":http://doc.qt.nokia.com/4.7/qgraphicsitem.html#events
-
A little more information: I put mouse event handlers in the scene like so: @void Layout2dScene::mousePressEvent (QGraphicsSceneMouseEvent * event)
{
QGraphicsScene::mousePressEvent(event);
QGraphicsItem * item = mouseGrabberItem();
}void Layout2dScene::mouseReleaseEvent (QGraphicsSceneMouseEvent * event)
{
QGraphicsItem * item = mouseGrabberItem();
QGraphicsScene::mouseReleaseEvent(event);
}
@ In both cases the item is the ComponentLayoutView object that contains the port view, not the PortLayoutView object. Nevertheless, the mousePressEvent is delivered to the PortLayoutView object that was clicked on. The mouseReleaseEvent goes to a generic handler in QGraphicsItem.Must we handle mouse events at the ComponentLayoutView level, then manually figure out which port, if any, the mouse is in? And if so why do mouse press, move, enter, leave, etc., events all seem to go to the PortLayoutView as we expected?
Thanks!
-
Oh, and just to be clear, PortLayoutView is declared as:
@class PortLayoutView : public QGraphicsItem
{
Q_DECLARE_TR_FUNCTIONS(PortLayoutView)public:
//...
protected:
virtual void mousePressEvent (QGraphicsSceneMouseEvent * event);
virtual void mouseReleaseEvent (QGraphicsSceneMouseEvent * event);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event);
@ -
Found a solution, but don't know if this is intentional behaviour on Qt's part. Note the commented-out line in the mousePressEvent handler:
@void PortLayoutView::mousePressEvent ( QGraphicsSceneMouseEvent * event )
{
boost::shared_ptr<PortBase> sp = port.lock();
if (!sp) return;
if (event->buttons() & Qt::LeftButton)
{
startPos = event->pos();
if (event->modifiers() & Qt::ControlModifier)
{
sp->setConnectionSource();
notifyAll(portSelectMsg);
}
}
// QGraphicsItem::mousePressEvent(event);
}
@
Thanks again! -
What I meant by "intentional behaviour" is that the program behaves differently when the base class handler is called, even if the handler doesn't do anything. One would assume that the QGraphicsItem::mousePressEvent(event); statement would be harmless, if slightly inefficient. This seems to be the case for the other mouse events. Perhaps one day I'll have some time to trace through the Qt source and research this in more depth.
Thanks!
-
I'm sure that will be a good learning experience!
For the main philosophy "this":http://doc.qt.nokia.com/4.7/graphicsview.html is also a good read.
-
I have a similar problem. I have a QGraphicsScene which hold QGraphicsView as parent. then I got QGraphicsProxyWidget holding myWidget derived from QWidget which can not receive mouseReleaseEvent but no problem receiving mousePressEvent. I have a QLabel and a QPushButton in myWidget Class. I tried debugging but It confused me when tracing into Qt internal class. Then I just simply change myWidget parent from QWidget to QPushButton and it worked. Hope my solution helps.
Thanks!
-
@Eddy said:
You didn't use the mousepressEvent from the base class and you don't need to if you reimplement it.
That's not necessarily true. The base class events implement certain functionality -they may select or deselect items, move items, etc. If you do not call a base class event, you lose that functionality. Worse still, if you reimplement some events, but not other, you might stumble into undefined behavior, as e.g. the base class receives a mouseRelease event where it expected to receive a mousePress first.
Before you decide not to call an event of the base class, you should
- Check which functionality it implements, and whether you can afford to do without it
- Check which events may be tied together, and whether you should reimplement all or none of them
- Think about the alternative of either calling the base class event before or after your custom event code