как заставить шестиугольник, унаследованный от QraphicsPolygonItem, изменить его цвет? - PullRequest
0 голосов
/ 18 ноября 2018

Я делаю школьный проект, и я застрял здесь. Я пытаюсь заставить свой шестиугольник постепенно менять свой цвет с желтого на синий. Это мой hexagon.hh:

#ifndef HEXAGON_HH
#define HEXAGON_HH

#include <QGraphicsPolygonItem>
#include <QPropertyAnimation>
#include "gamecontroller.hh"


class GameController;

class Hexagon : public QGraphicsPolygonItem
{
public:
    Hexagon(QGraphicsItem *parent = 0);
    ~Hexagon();

    GameController* _controller;
    Common::CubeCoordinate _coord;

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent* event);

};

#endif // HEXAGON_HH

Я пытался использовать QPropertyAnimation так:

QPropertyAnimation* animation = new QPropertyAnimation(_Tilemap.at(tileCoord)->hexagon_, "brush");
animation->setDuration(10000);
animation->setStartValue(QBrush(Qt::yellow()));
animation->setEndValue(QBrush(Qt::blue()));
animation->start();

Но его нельзя было использовать в классе шестиугольника, поэтому он не работал. Как я могу заставить шестиугольник изменить свой цвет, чтобы была анимация?

e: вот ошибка, которую я получаю при попытке использовать QPropertyAnimation:

/home/litmanen/test/UI/gamecontroller.cpp:256: error: no matching function for call to ?QPropertyAnimation::QPropertyAnimation(Hexagon*&, const char [6])?
     QPropertyAnimation* animation = new QPropertyAnimation(_Tilemap.at(tileCoord)->hexagon_, "brush");

1 Ответ

0 голосов
/ 18 ноября 2018

Ошибка вызвана тем, что QPropertyAnimation применяется только к QObject, в вашем случае QGraphicsPolygonItem - нет.Таким образом, возможное решение заключается в наследовании от QObject:

*. H

#ifndef HEXAGON_H
#define HEXAGON_H

#include <QBrush>
#include <QGraphicsPolygonItem>
#include <QObject>

class Hexagon : public QObject, public QGraphicsPolygonItem
{
    Q_OBJECT
    Q_PROPERTY(QBrush brush READ brush WRITE setBrush)
public:
    explicit Hexagon(QObject *parent=nullptr);

    GameController* _controller;
    Common::CubeCoordinate _coord;
protected:
    void mousePressEvent(QGraphicsSceneMouseEvent* event);

};

#endif // HEXAGON_H

*. Cpp

#include "hexagon.h"

Hexagon::Hexagon(QObject *parent):
    QObject(parent)
{
    /*another code*/
}

void Hexagon::mousePressEvent(QGraphicsSceneMouseEvent* event){
    /*another code*/
}

С другой стороны, он все еще не работает, так как для QBrush нет интерполятора, поэтому решение состоит в том, чтобы реализовать интерполятор (используйте интерполятор , это решение )

static QVariant brushInterpolator(const QBrush &start, const QBrush &end, qreal progress)
{
    QColor cstart = start.color();
    QColor cend = end.color();
    int sh = cstart.hsvHue();
    int eh = cend.hsvHue();
    int ss = cstart.hsvSaturation();
    int es = cend.hsvSaturation();
    int sv = cstart.value();
    int ev = cend.value();
    int hr = qAbs( sh - eh );
    int sr = qAbs( ss - es );
    int vr = qAbs( sv - ev );
    int dirh =  sh > eh ? -1 : 1;
    int dirs =  ss > es ? -1 : 1;
    int dirv =  sv > ev ? -1 : 1;

    return QBrush(QColor::fromHsv( sh + dirh * progress * hr,
                                   ss + dirs * progress * sr,
                                   sv + dirv * progress * vr), progress > 0.5 ? Qt::SolidPattern : Qt::Dense6Pattern  );

}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    qRegisterAnimationInterpolator<QBrush>(brushInterpolator);
    // ...

Другое решение состоит в том, чтобы реализовать ту же логику с QColor, для которой не требуется интерполятор:

*. H

#ifndef HEXAGON_H
#define HEXAGON_H

#include <QGraphicsPolygonItem>
#include <QObject>

class Hexagon : public QObject, public QGraphicsPolygonItem
{
    Q_OBJECT
    Q_PROPERTY(QColor color READ color WRITE setColor)
public:
    explicit Hexagon(QObject *parent=nullptr);
    QColor color() const;
    void setColor(const QColor &color);

    GameController* _controller;
    Common::CubeCoordinate _coord;
protected:
    void mousePressEvent(QGraphicsSceneMouseEvent* event);
};

#endif // HEXAGON_H

*. Cpp

#include "hexagon.h"

#include <QBrush>

Hexagon::Hexagon(QObject *parent):
    QObject(parent)
{
    QBrush b = brush();
    b.setStyle(Qt::SolidPattern);
    setBrush(b);
    /*another code*/
}

QColor Hexagon::color() const
{
    return brush().color();
}

void Hexagon::setColor(const QColor &color)
{
    QBrush b = brush();
    b.setColor(color);
    setBrush(b);
}

void Hexagon::mousePressEvent(QGraphicsSceneMouseEvent* event){
    /*another code*/
}

Затем вы используете «color» вместо «brush»:

QPropertyAnimation* animation = new QPropertyAnimation(_Tilemap.at(tileCoord)->hexagon_, "color");
animation->setDuration(10000);
animation->setStartValue(QColor(Qt::yellow));
animation->setEndValue(QColor(Qt::blue));
animation->start();

Другое простое решение - использовать QVariantAnimation:

auto it = _Tilemap.at(tileCoord)->hexagon_;
QVariantAnimation *animation = new QVariantAnimation;
QObject::connect(animation, &QVariantAnimation::valueChanged, [it](const QVariant & v){
    it->setBrush(QBrush(v.value<QColor>()));
});
animation->setDuration(10000);
animation->setStartValue(QColor(Qt::yellow));
animation->setEndValue(QColor(Qt::blue));
animation->start();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...