如何使从QraphicsPolygonItem继承的六边形更改其颜色?

时间:2018-11-18 12:52:32

标签: c++ qt

我正在做一个学校项目,却被困在这里。我正在尝试使六边形逐渐从黄色变为蓝色。这是我的六角形。

def word():
   if ["T,Y,R"] in (word[3]):
      return True
   if ["R,Y,F,M"] in (word[4]):
      return True
      else:
   return False

我试图像这样使用QPropertyAnimation:

#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

但是它不能在六角形上使用,所以它不起作用。我该如何使六边形更改其颜色,以产生动画?

e:这是我尝试使用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();

1 个答案:

答案 0 :(得分:1)

由于QPropertyAnimation仅适用于QObject而导致错误,原因是QGraphicsPolygonItem不适用于QObject。因此,可能的解决方案是从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的插补器,它仍然不起作用,因此解决方案是实现一个插补器(使用this solution的插补器)

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*/
}

然后您使用“颜色”代替“画笔”:

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();