How do you define shape for pie slice and animate?
Unsolved
General and Desktop
-
I've a subclass of QGraphicsItem,
Slice
:#define whats16 16 Slice::Slice(float start, float sweep, QColor color) : m_start(start), m_sweep(sweep), m_color(color){ setAcceptHoverEvents(true); } QRectF Slice::boundingRect() const { return QRectF(0,0,200,200); } void Slice::paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*){ painter->setRenderHint(QPainter::Antialiasing); painter->setPen(Qt::white); painter->setBrush(m_color); painter->drawPie(boundingRect(), whats16*m_start, whats16*m_sweep); } void Slice::hoverEnterEvent(QGraphicsSceneHoverEvent*){ dx = 10 * cos(whats16*m_start + whats16*m_sweep / 2); dy = 10 * sin(whats16*m_start + whats16*m_sweep / 2); moveBy(-dx, dy); } void Slice::hoverLeaveEvent(QGraphicsSceneHoverEvent*){ dx = 10 * cos(whats16*m_start + whats16*m_sweep / 2); dy = 10 * sin(whats16*m_start + whats16*m_sweep / 2); moveBy(dx, -dy); }
and in
PieView
I add slice:PieView::PieView(QWidget *parent) : QGraphicsView(parent){ auto scene = new QGraphicsScene(this); scene->setBackgroundBrush(Qt::black); setScene(scene); QRandomGenerator rand; for (int i = 0; i < 360; i+=45) { auto color = QColor::fromRgb(rand.global()->bounded(0,255), rand.global()->bounded(0,255), rand.global()->bounded(0,255)); auto slice = new Slice(i, 45, color); scene->addItem(slice); } }
and this PieView is the only child of
Window
:Window::Window(QWidget *parent) : QWidget(parent){ auto pie = new PieView(this); auto lay = new QVBoxLayout(this); lay->setContentsMargins(0,0,0,0); lay->addWidget(pie); setLayout(lay); }
all
boundingRect
of those slices, probably, overlaps so only one slice gets thosehoverEvents
:how to return the exact
shape
of those slices instead ofboundingRect
? One more thing, I want to animate its color and position on hover enter and leave like this:found an example in
QGraphicsItemAnimation
doc but couldn't fathom! How to do that? -
With these in slice:
#define whats16 16 Slice::Slice(float start, float sweep, QColor color) : m_start(start), m_sweep(sweep), m_color(color){ m_rect = QRectF(0,0,200,200); m_path = QPainterPath(QPointF(m_rect.width() / 2, m_rect.height() / 2)); m_path.arcTo(m_rect, m_start, m_sweep); m_path.closeSubpath(); dx = 10 * cos(m_start + m_sweep / 2); dy = 10 * sin(m_start + m_sweep / 2); setAcceptHoverEvents(true); } QRectF Slice::boundingRect() const { return m_rect; } QPainterPath Slice::shape() const { return m_path;} void Slice::hoverEnterEvent(QGraphicsSceneHoverEvent*){ moveBy(dx, dy); } void Slice::hoverLeaveEvent(QGraphicsSceneHoverEvent*){ moveBy(-dx, -dy); } void Slice::paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*){ painter->setRenderHint(QPainter::Antialiasing); painter->setPen(Qt::white); painter->setBrush(m_color); painter->drawPie(boundingRect(), whats16 * m_start, whats16 * m_sweep); }
hit test is ok BUT
moveBy
doesn't work as expected: -
Drawing direction and radian were the problem. With these:
#define whats16 16 Slice::Slice(float start, float sweep, QColor color, QGraphicsItem* parent) : QGraphicsItem(parent), m_start(start), m_sweep(sweep), m_color(color){ m_realColor = color; m_rect = QRectF(0,0,200,200); m_path = QPainterPath(QPointF(m_rect.width() / 2, m_rect.height() / 2)); m_path.arcTo(m_rect, -m_start, -m_sweep); m_path.closeSubpath(); dx = 10 * cos((m_start + m_sweep / 2) * M_PI / 180); dy = 10 * sin((m_start + m_sweep / 2) * M_PI / 180); setAcceptHoverEvents(true); } QRectF Slice::boundingRect() const { return m_rect; } QPainterPath Slice::shape() const { return m_path;} void Slice::hoverEnterEvent(QGraphicsSceneHoverEvent*){ m_color = Qt::gray; moveBy(dx, dy); } void Slice::hoverLeaveEvent(QGraphicsSceneHoverEvent*){ m_color = m_realColor; moveBy(-dx, -dy); } void Slice::paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*){ painter->setRenderHint(QPainter::Antialiasing); painter->setPen(Qt::white); painter->setBrush(m_color); painter->drawPie(m_rect, whats16 * -m_start, whats16 * -m_sweep); }
Now, slice moves perfectly:
BUT the whole pie moves for a while (5 times as I start hovering over different slices). Why does it move?