Я хочу оживить цвет QBrush
, Для более подробной информации смотрите код ниже
Это мой .h файл
class Cell : public QObject, public QGraphicsRectItem
{
Q_OBJECT
Q_PROPERTY(QBrush brush READ brush WRITE set_Brush)
public:
QBrush _brush() const;
void set_Brush(const QBrush&);
Cell(QGraphicsItem *parent = 0); //конструктор
}
Это мой файл .cpp
Cell::Cell(QGraphicsItem *parent)
: QObject(), QGraphicsRectItem(parent)
{
this->setRect(0, 0, Scale, Scale);
}
QBrush Cell::_brush() const
{
return this->brush();
}
void Cell::set_Brush(const QBrush & brush)
{
this->setBrush(brush);
}
и это анимация:
QPropertyAnimation* animation = new QPropertyAnimation(selectedCell, "brush");
animation->setDuration(10000);
animation->setStartValue(QBrush(QColor(255,0,0)));
animation->setEndValue(QBrush(QColor(0,255,0)));
animation->start();
Но это не работает, ничего не происходит, цвет кисти тот же, что был раньше. Что я должен сделать, чтобы это исправить?
QT не знает, как выполнить переход между стартом QBrush
и конец QBrush
, QBrush
имеет больше свойств, чем просто цвет, вы можете предусмотреть анимацию, где цвет остается неизменным, и меняется только шаблон. Таким образом, нет поддержки по умолчанию для этого вида перехода.
Как намекнул @fscibe, вы можете написать свой собственный метод для выполнения перехода, в котором вы указываете, как вы хотите перейти от одного из них. QBrush
к другому.
Грубый пример:
QVariant myColorInterpolator(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 app(argc,argv);
QGraphicsView *view = new QGraphicsView;
QGraphicsScene *scene = new QGraphicsScene;
QDialog *dialog = new QDialog;
QGridLayout *layout = new QGridLayout;
layout->addWidget(view);
view->setScene(scene);
scene->setSceneRect(-500,-500,1000,1000);
dialog->setLayout(layout);
dialog->show();
Cell *selectedCell = new Cell;
scene->addItem(selectedCell);
qRegisterAnimationInterpolator<QBrush>(myColorInterpolator);
QPropertyAnimation* animation = new QPropertyAnimation(selectedCell, "brush");
animation->setDuration(10000);
animation->setStartValue(QBrush(Qt::blue));
animation->setEndValue(QBrush(Qt::red));
animation->start();
return app.exec();
}
Очевидно, что это фиктивный пример, и для изменения цвета он заново изобретает колесо, как вы видите из ответа fscibe, но это должно показать вам, что вы определяете свой собственный метод перехода, например, для QBrush
Вы можете сделать больше, чем просто изменить цвет.
Вы должны предоставить свою собственную реализацию для интерполяции по типу QBrush.
Из документа Qt:
«QPropertyAnimation интерполирует свойства Qt. Поскольку значения свойств хранятся в QVariants, класс наследует QVariantAnimation и поддерживает анимацию тех же типов вариантов, что и его суперкласс.«(http://qt-project.org/doc/qt-4.8/qpropertyanimation.html)
См. Список поддерживаемых типов и пример реализации пользовательской интерполяции здесь, в разделе «Подробное описание»:
http://qt-project.org/doc/qt-4.8/qvariantanimation.html
Альтернативой может быть интерполирование только между QColors, а затем обновление кисти:
class Cell : public QObject, public QGraphicsRectItem
{
Q_OBJECT
Q_PROPERTY(QColor color READ _color WRITE set_Color)
public:
Cell()
{
setRect(0,0,100,100); // non-zero rect
m_brush.setStyle(Qt::SolidPattern); // fill color is active
}
QColor _color() const
{
return brush().color();
}
void set_Color(const QColor& c)
{
m_brush.setColor(c);
setBrush( m_brush );
}
QBrush m_brush;
};
С анимацией:
QPropertyAnimation* animation = new QPropertyAnimation(selectedCell, "color");
animation->setDuration(10000);
animation->setStartValue(QColor(255,0,0));
animation->setEndValue(QColor(0,255,0));
animation->start();