问题的提出:
最近利用Graphics View Framework 实现一需求,其中要求鼠标按住QGraphicsWidget实现随意拖动,但调试发现鼠标、键盘的任何消息,QGraphicsWidget都无法响应,ItemIsMovable 、ItemIsSelectable 、ItemIsFocusable都已经通过如下代码设置:
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemSendsGeometryChanges | QGraphicsItem::ItemUsesExtendedStyleOption);
接受鼠标悬浮事件也设置为true:
setAcceptHoverEvents(true);
依然不响应鼠标键盘消息,即下面代码都不响应:
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
virtual void keyPressEvent(QKeyEvent *event) override;
virtual void keyReleaseEvent(QKeyEvent *e) override;
经过艰苦排查,发现必须实现下面两个函数才能响应鼠标键盘消息:
QRectF CComponentLineWidget::boundingRect() const
{
return QRectF(0, 0, 500, 500);
}
QPainterPath CComponentLineWidget::shape() const
{
QPainterPath path;
path.addRect(boundingRect());
return path;
}
其中CComponentLineWidget是QGraphicsWidget的派生子类。请注意:如果不实现shape函数,则shape函数默认返回的是QPainterPath为空的对象,只有鼠标落在一个由shape函数返回非空QPainterPath对象表示区域范围内时,才会接收鼠标、键盘消息。
总结:
要使QGraphicsItem、QGraphicsWidget响应鼠标、键盘消息,则必须满足:
- 必须实现boundingRect()函数,且该函数返回的矩形区域不能过小。
- 必须实现shape()函数,且该函数返回的QPainterPath对象不能为空,所表示的区域不能过小。
- 通过setFlags函数设置ItemIsSelectable 、ItemIsFocusable标识。