在QGraphicsScene中有时会删除绘制的自定义项目

时间:2016-01-30 14:56:36

标签: c++ qt

我有一个自定义图形项,即从QGraphicsEllipseItem开始。具体来说,我的自定义项目只是一个带有标签的圆圈(让我称之为“顶点”)。我理解这个想法:从基类继承,实现某些方法,你就完成了。

标题在这里:

#ifndef VERTEX_H
#define VERTEX_H

#include <QPointF>
#include <QGraphicsEllipseItem>

class Vertex : public QGraphicsEllipseItem
{
public:
    Vertex(const QPointF& pos, int label, int size = 20) : pos_(pos), label_(label), size_(size)  { }

    QRectF boundingRect() const;

protected:
    virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0);

private:
    QPointF pos_;
    int label_;
    int size_;
};

#endif // VERTEX_H

这里的实施:

// vertex.cpp
#include "vertex.h"
#include <QPainter>

QRectF Vertex::boundingRect() const
{
    return QGraphicsEllipseItem(pos_.x(), pos_.y(), size_, size_).boundingRect();
}

void Vertex::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
    painter->drawEllipse(pos_, size_, size_);
    painter->drawText(pos_, QString::number(label_));
}

因为我的对象 是一个椭圆,我想在椭圆中利用边界矩形实现。然而,当我画画时,似乎有些事情发生了。特别是,我可能会看到这样的事情:

enter image description here

(以上内容来自QGraphicsScene)。

  1. boundingRect的实施是否已关闭?
  2. 是否有其他因素导致“糟糕”的绘画?我在用户单击QGraphicsScene时绘制了一个Vertex,因此QPointF的构造函数的Vertex参数是从mouseEvent->scenePos();提供的,其中mouseEvent的类型为QGraphicsSceneMouseEvent*

1 个答案:

答案 0 :(得分:2)

首先,你没有获得任何形式,并且不需要继承QGraphicsEllipseItem,最好从干净的平台开始,只需继承QGraphicsItem。股票椭圆项目不会从中心点和半径绘制椭圆,因此其边界矩形实现将与您绘制的内容不匹配。

由于您基本上绘制了一个具有中心和半径的圆,因此正确的边界矩形实现应返回QRectF(pos_.x() - size_ / 2, pos.y() - size_ /2, size_, size_)

您当前的实施不会返回一个覆盖您的项目的矩形,而是从其中心开始并远离外部:

enter image description here

好的,多一点帮助:

  • 区分绝对坐标和相对坐标 - 鼠标点击产生的点实际上不会用于设置圆心,而是图形项的位置
  • 圈子的中心实际上是相对于该项目的,因此它将是QPointF(radius, radius),在您的情况下是size_的一半
  • 你真的不需要存储中心点
  • 如果你的边界矩形实现正确,一切都会正确绘制
  • 如果您希望项目重叠,则必须为画家设置画笔,否则只会画出圆圈的轮廓

因此,在所需的位置和直径处创建一个圆并绘制它可归结为:

class Circle : public QGraphicsItem {
public:
    Circle(QPointF c, int r) {
        setPos(QPointF(c.x() - r, c.y() - r));
        radius = r;
    }
    QRectF boundingRect() const { return QRectF(pos(), pos() + QPointF(radius * 2, radius * 2)); }
    void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0) {
        painter->setBrush(Qt::white);
        painter->drawEllipse(boundingRect());
        painter->drawText(boundingRect().center(), "C");
    }
private:
    int radius;
};

现在这一切都正确:

enter image description here