c++ - Qt QGraphicsScene items() 段错误

标签 c++ qt qgraphicsitem qgraphicsscene

<分区>

我开始了解 QGraphicsScene 和 Qt 的整个 QGraphics 部分。现在我正在尝试创建一个管理贝塞尔曲线的程序(用于建模机身部分,这就是代码中有“部分”的原因)。

实现 QGraphicsScene 类:

class SectionScene : public QGraphicsScene
{
    Q_OBJECT
public:
    explicit SectionScene(Database* database, QObject *parent = 0);
    BezierCurve* currentCurve();
signals:

public slots:
    void focusCurve(BezierCurve* curve);
    void addNode(BezierNode* node);
private:
    void mousePressEvent(QGraphicsSceneMouseEvent* e);
    Database* database;
    BezierCurve* m_currentCurve;
    QPainter* painter;
};

SectionScene::SectionScene(Database* database, QObject *parent) :
    QGraphicsScene(parent)
{
    this->database = database;
    this->setSceneRect(-100,-100,200,200);
    connect(database,SIGNAL(curveFocus(BezierCurve*)),this,SLOT(focusCurve(BezierCurve*)));
    connect(database,SIGNAL(nodeAdd(BezierNode*)),this,SLOT(addNode(BezierNode*)));
    painter = new QPainter();
    addItem(new QGraphicsRectItem(QRectF(0,0,100,100)));
}

void SectionScene::addNode(BezierNode *node)
{
    addItem(node);
    if (node->leftControlPoint()) addItem(node->leftControlPoint());
    if (node->rightControlPoint()) addItem(node->rightControlPoint());
    update();
}

void SectionScene::mousePressEvent(QGraphicsSceneMouseEvent *e)
{
    if (e->button() == Qt::LeftButton && e->modifiers() == Qt::ControlModifier) {
        BezierNode* node = new BezierNode(e->scenePos());
        currentCurve()->appendNode(node);

    } else {
        if (items(e->scenePos()).size()) {
            QGraphicsScene::mousePressEvent(e);
        }
    }
}

BezierNode类,也就是QGraphicsItem:

class BezierNode : public QGraphicsItem
{
    Q_INTERFACES(QGraphicsItem)
public:
    enum Type {Symmetric, Smooth, Angular};
    BezierNode(QPointF point = QPointF(0,0), Type type = Symmetric);
    void setPoint(QPointF point);
    QPointF& point();
    void setLeftControlPoint(BezierControlPoint*);
    BezierControlPoint* leftControlPoint();
    void setRightControlPoint(BezierControlPoint*);
    BezierControlPoint* rightControlPoint();
    void setType(Type);
    Type type();

    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    QPainterPath shape() const;



public slots:
//  void mousePressEvent(QGraphicsSceneMouseEvent *event);
    //  void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
    bool sceneEvent(QEvent *event);
private:
    QPointF m_point;
    BezierControlPoint* m_leftControlPoint;
    BezierControlPoint* m_rightControlPoint;
    Type m_type;
    bool m_selected = false;
    bool m_hovered = false;
};

BezierNode::BezierNode(QPointF point, Type type) : QGraphicsItem()
{
    m_point = point;
    m_type = type;
    if (type == Symmetric) {
        BezierControlPoint* leftControlPoint = new BezierControlPoint(point - QPoint(30,0),this);
        BezierControlPoint* rightControlPoint = new BezierControlPoint(point + QPoint(30,0),this);
        setLeftControlPoint(leftControlPoint);
        setRightControlPoint(rightControlPoint);
    }
//  setFlags(ItemIsMovable);
}

QRectF BezierNode::boundingRect() const
{
    qreal size = 7;
    QPointF topLeft = m_point - QPointF(size,-size);
    QPointF bottomRight = m_point + QPointF(size, -size);
    return QRectF(topLeft,bottomRight);
}

void BezierNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->drawEllipse(boundingRect());
}

QPainterPath BezierNode::shape() const
{

    QPainterPath path;
    path.addEllipse(boundingRect());
}

SectionScene 中的 mousePressEvent 行为如下:使用 ctrl-modifier,它正确地创建了 BezierNode 并将其绘制在 View 上(只有一个使用的 View ,场景绑定(bind)到它)。如果在没有修饰符的情况下左键单击,如果我在 BezierNode 形状之外单击,则一切正常。但是如果我点击它,就会在 items(e->scenePos()) 出现段错误。 itemAt(..) 也是如此,当我尝试只使用 QGraphicsScene::mousePressEvent(e) 时。现在好几个小时都无法克服它,所以我想听听你的想法。此外,BezierNode 中的 sceneEvent(QGraphicsSceneEvent* event) 会在每个场景事件上触发,即使它与此项无关。它应该如何?

可在 git 找到完整的可编译项目.

最佳答案

QGraphicsItem 的 boundingRect 和 shape 函数负责在调用 QGraphicsScene::items 或 itemAt 时检查位置是否与项目发生碰撞。

您已将此声明为形状函数:-

QPainterPath BezierNode::shape() const
{

    QPainterPath path;
    path.addEllipse(boundingRect());
}

所以你没有返回你创建的形状。

虽然这可能不是段错误的原因,但它仍然会给您带来问题。

关于c++ - Qt QGraphicsScene items() 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26257245/

相关文章:

c++ - 反转数组而不改变零的位置

QT ffmpeg 设置

c++ - QT中如何让弹出窗口成为顶层窗口?

python - 在QGraphicsItem上添加动画时遇到的一个问题

c++ - 如何向 shared_ptr 添加偏移量?

c++ - qt - 对 `_imp__Z*' 的 undefined reference

c++ - 串行代码的并行 MPI 实现

c++ - Qt4 Designer 使用 QTableWidget 创建对话框

qt - 缩放QGraphicsView时要调整QPen厚度吗?

c++ - 如何使 QGraphicsItem 的位置依赖于另一个 QGraphicsItem?