Reputation: 453
I have a custom graphics item, that is inherting from QGraphicsEllipseItem
. Specifically, my custom item is just a circle with a label attached to it (let me call it a "vertex"). I understand the idea: inherit from the base class, implement certain methods, and you are done.
The header is here:
#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
The implementations here:
// 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_));
}
Because my object really is an ellipse, I'd like to exploit the bounding rectangle implementation in an ellipse. However, something seems to be off when I draw things. In particular, I might see something like this:
(The above is cropped from a QGraphicsScene).
boundingRect
off?QPointF
argument to the constructor of Vertex
is provided from mouseEvent->scenePos();
, where mouseEvent is of type QGraphicsSceneMouseEvent*
.Upvotes: 0
Views: 466
Reputation: 49329
First of all, you don't gain anything form and don't really need to inherit QGraphicsEllipseItem
, it is better to start on a clean slate, just inherit QGraphicsItem
. The stock ellipse item doesn't draw the ellipse from a center point and radius, so its bounding rect implementation will not match what you are drawing.
Since you essentially draw a circle with a center and radius, your correct bounding rect implementation should return a QRectF(pos_.x() - size_ / 2, pos.y() - size_ /2, size_, size_)
.
Your current implementation doesn't return a rectangle which covers your item, instead it begins at its center and goes far outside:
OK, a little more help:
QPointF(radius, radius)
, in your case half of size_
So creating a circle at the desired position and diameter and drawing it boils down to something like this:
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;
};
And it all draws correctly now:
Upvotes: 2