【发布时间】:2019-01-04 07:54:01
【问题描述】:
我正在尝试对QGraphicsRectItem 进行简单的扩展,它允许我调整矩形的大小并用鼠标移动它。我在要启用拖动的角上使用椭圆拱对手柄建模,我将其实现为QGraphicsEllipseItems:
class QGraphicsBoxWithHandlesItem : public QObject, public QGraphicsRectItem
{
Q_OBJECT
typedef enum {
None,
BottomLeft,
TopRight
} ActiveAnchor;
private:
QGraphicsEllipseItem m_anchorBottomLeft;
QGraphicsEllipseItem m_anchorTopRight;
float m_anchorRadius;
ActiveAnchor m_activeAnchor;
public:
QGraphicsBoxWithHandlesItem(QRectF r, float handlesRadius = 20.0, QGraphicsItem *parent = nullptr);
void setAnchorRadius(float radius);
float getAnchorRadius();
QPainterPath shape() const;
protected:
void mousePressEvent(QGraphicsSceneMouseEvent * event);
void mouseMoveEvent(QGraphicsSceneMouseEvent * event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent * event);
};
我希望能够检测矩形和手柄项目上的点击(这是必要的,因为如果矩形变得太小,手柄是唯一容易点击的区域),所以我想我会扩展 @987654325 @ 将子项的路径添加到返回的QPainterPath (调整坐标以使其相对于父项):
QPainterPath QGraphicsBoxWithHandlesItem::shape() const
{
auto curShape = QGraphicsRectItem::shape();
curShape.addPath( mapFromItem(&m_anchorBottomLeft, m_anchorBottomLeft.shape()) );
curShape.addPath( mapFromItem(&m_anchorTopRight, m_anchorTopRight.shape()) );
return curShape;
}
然而,我得到的是,现在手柄区域内的点击被完全忽略,只处理矩形中心区域的点击。
当项目具有非平凡的形状时,扩展其可点击区域的正确方法是什么?
更新:我尝试在句柄上设置ItemIsSelectable 标志,现在,如果我单击它,我会看到它被选中。但是,我仍然没有在父母中得到任何mousePressEvent。我做错了什么?
编辑:
这是构造函数实现:
QGraphicsBoxWithHandlesItem::QGraphicsBoxWithHandlesItem( QRectF r, float handlesRadius, QGraphicsItem * parent) :
QGraphicsRectItem(parent),
m_anchorRadius(handlesRadius),
m_activeAnchor(None)
{
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemIsSelectable);
setRect(r);
m_anchorBottomLeft.setRect(-m_anchorRadius, -m_anchorRadius, m_anchorRadius*2, m_anchorRadius*2);
m_anchorBottomLeft.setPos(rect().bottomLeft());
m_anchorBottomLeft.setSpanAngle(90 * 16); // angle is in 16ths of degree
m_anchorBottomLeft.setParentItem(this);
m_anchorTopRight.setRect(-m_anchorRadius, -m_anchorRadius, m_anchorRadius*2, m_anchorRadius*2);
m_anchorTopRight.setPos(rect().topRight());
m_anchorTopRight.setStartAngle(180 * 16); // angle is in 16ths of degree
m_anchorTopRight.setSpanAngle(90 * 16); // angle is in 16ths of degree
m_anchorTopRight.setParentItem(this);
}
【问题讨论】:
-
您是如何将 m_anchorBottomLeft 和 m_anchorTopRight 添加到场景中的?
-
好问题.. 我不确定。它们是根
Rect项目的子项目,我将其添加到场景中。我假设孩子是与父母一起添加的,但我不确定情况是否如此 -
当我们需要解决方案时,我们选择了github.com/cesarbs/sizegripitem
-
@ypnos 谢谢,我一定会看看的! (我希望我昨天找到它..)但是,我仍然想知道我的代码中发生了什么,如果只是为了了解当我再次需要它时如何做到这一点:)
标签: c++ qt qt5 qgraphicsscene qgraphicsitem