Получить промежуточный цвет из градиента

Скажем, у меня есть градиент лайнера, как показано на рисунке:

QLinearGradient linearGrad(QPointF(0, 0), QPointF(0, 100));
linearGrad.setColorAt(1, Qt::red);
linearGrad.setColorAt(0.5, Qt::yellow);
linearGrad.setColorAt(0, Qt::green);

Как получить цвет точки QPointF(0, 28.5) в этом градиенте?

Действительно, я хочу иметь такое распределение цветов, чтобы иметь возможность выбирать промежуточные цвета. Меня не волнует, делается ли это с помощью QLinearGradient или чего-то еще.


person Narek    schedule 22.07.2010    source источник


Ответы (4)


Есть только один способ сделать это:

В классе QPixmap есть статический член
QPixmap QPixmap::grabWindow( WId window, int x = 0, int y = 0, int width = -1, int height = -1 )

1) нарисуйте свой градиент на своем виджете;

2) с помощью этой функции захватите поверхность вашего виджета в растровое изображение; WId можно получить от QWidget::effectiveWinId ();

3) преобразовать растровое изображение токена в QImage (есть конструктор);

4) int QImage::pixelIndex( int x, int y ) возвращает индекс пикселя (x, y) в таблице цветов QImage. В вашем случае вы должны рассчитать процентное значение от высоты виджета ( pWidget->height() / 100 * 28.5 ).

5) QRgb QImage::color( int i ) возвращает цвет в таблице цветов с индексом i.

Итак, возвращенный цвет — это цвет, который вы искали.

person Pie_Jesu    schedule 18.03.2011

Я сохраняю цвета градиента в одном QList, а затем вычисляю с интерполяцией цветов.

QColor ColorGradient::getColor(double value)
{
  qDebug()<< "ColorGradient::getColor:";
    //Asume mGradientColors.count()>1 and value=[0,1]
    double stepbase = 1.0/(mGradientColors.count()-1);
    int interval=mGradientColors.count()-1; //to fix 1<=0.99999999;

      for (int i=1; i<mGradientColors.count();i++)//remove begin and end
        {
            if(value<=i*stepbase ){interval=i;break;}
        }
       double percentage = (value-stepbase*(interval-1))/stepbase;
       QColor color(interpolate(mGradientColors[interval],mGradientColors[interval-1],percentage));        
       return color;
}
QColor ColorGradient::interpolate(QColor start,QColor end,double ratio)
{
    int r = (int)(ratio*start.red() + (1-ratio)*end.red());
    int g = (int)(ratio*start.green() + (1-ratio)*end.green());
    int b = (int)(ratio*start.blue() + (1-ratio)*end.blue());
    return QColor::fromRgb(r,g,b);
}
person user2232395    schedule 26.03.2015
comment
Так как это старый ответ на вопрос. Почему это лучший вопрос, и это может помочь в вопросе ОП? Пожалуйста, избегайте публикации вопроса, на который был принят ответ. - person bcesars; 26.03.2015
comment
Я думаю, что это хороший ответ. Для других, ищущих, как я, я нахожу это гораздо более полезным, чем принятый ответ. - person elegant dice; 08.09.2017

Ответ Мэйсона Чжана работает, и очень хорошо! Пусть controlPoints() возвращает QMap<qreal,QColor> с ключом от 0,0 до 1,0. Вот как я это сделал (спасибо Мейсону Чжану)

QColor getColor(qreal key) const
{
    // key must belong to [0,1]
    key = Clip(key, 0.0, 1.0) ;

    // directly get color if known
    if(controlPoints().contains(key))
    {
        return controlPoints().value(key) ;
    }

    // else, emulate a linear gradient
    QPropertyAnimation interpolator ;
    const qreal granularite = 100.0 ;
    interpolator.setEasingCurve(QEasingCurve::Linear) ;
    interpolator.setDuration(granularite) ;
    foreach( qreal key, controlPoints().keys() )
    {
        interpolator.setKeyValueAt(key, controlPoints().value(key)) ;
    }
    interpolator.setCurrentTime(key*granularite) ;
    return interpolator.currentValue().value<QColor>() ;
}
person azf    schedule 26.09.2011

QVariantAnimation имеет аналогичную функциональность, и QVariantAnimation::keyValueAt может вернуть нужное вам значение. Вы можете войти в код QVariantAnimation и посмотреть, как работает keyValueAt.

person Mason Zhang    schedule 22.07.2010
comment
Я понятия не имею, как использовать абстрактный класс QVariantAnimation. Пожалуйста, если у вас есть пример, продемонстрируйте его. - person Narek; 22.07.2010
comment
просто используйте функции ниже, как то, что вы сделали QLinearGradient: - QVariantAnimation::setStartValue (const QVariant & value) - QVariantAnimation::setKeyValueAt(qreal step, const QVariant & value); - QVariantAnimation::setEndValue (const QVariant & value); Затем получите значение в точке с помощью - QVariantAnimation::keyValueAt ( qreal step ); Проблема в том, что QVariantAnimation не поддерживает QColor. Я не уверен, работает ли преобразование QColor в Int или нет. - person Mason Zhang; 23.07.2010
comment
QVariantAnimation — это абстрактный класс. Это должно быть унаследовано и реализовано. - person Narek; 23.07.2010
comment
почему бы не попробовать конкретный класс QPropertyAnimation? - person Mason Zhang; 24.07.2010