c++ - 绘制的自定义项目有时会在 QGraphicsScene 中被砍掉

标签 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,因此 Vertex 的构造函数的 QPointF 参数由 mouseEvent->scenePos();,其中 mouseEvent 的类型为 QGraphicsSceneMouseEvent*

最佳答案

首先,你没有获得任何形式,也不需要继承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

关于c++ - 绘制的自定义项目有时会在 QGraphicsScene 中被砍掉,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35103239/

相关文章:

c++ - QT 中 QDoubleSpinBoxes 的多个范围

java - 替代 Java 中的固定大小数组?

c++ - 有什么方法可以知道目录是否包含子目录?

c++ - 有效地返回二维 vector

c++ - 使用 Qt 和 C++ 创建 SNMP 代理

Qt:将变量传递给子项目

c++ - 为 Qt 中 Items 交集定义的区域着色

c++ - 如何删除一组 vector 中的 vector 元素?

c++ - QMenu 中 QAction 的所有权

c++ - 排序后如何从sqlite中获取数据?