2010-07-22 4 views
2

Say У меня есть градиент хвостовика, как показано:Получить промежуточный цвет из градиента

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 или что-то еще.

ответ

3

Существует единственный способ сделать это:

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

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

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

3) преобразуйте pixmap в токен в QImage (имеется конструктор);

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

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

Так вернулся Цвет - это цвет, который вы искали.

1

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

+1

Я понятия не имею, как использовать абстрактный класс класса QVariantAnimation. Пожалуйста, если вы, например, продемонстрируете это. – Narek

+1

просто используйте функции ниже как то, что вы сделали 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 работает или нет. –

+1

QVariantAnimation - абстрактный класс. Он должен быть унаследован и реализован. – Narek

3

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

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

хранить цвета градиента в одном 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); 
} 
+0

Поскольку это старый ответный вопрос. Почему это самый лучший вопрос, и это может помочь вопросу ФП? Пожалуйста, не ставьте вопрос, который принял ответ. – bcesars

+0

Я думаю, что это хороший ответ.Для других, ищущих меня, я нахожу его гораздо более полезным, чем принятый ответ. –