2016-10-18 2 views
0

Используя QtQuick, можно ли взять существующий цвет, определенный RGB, и обесцветить его, не прибегая к Javascript?Как удалить насыщенный цвет, определенный RGB в декларативном QML

+1

Если вы просто хотите обесцветить что-то на экране, вы можете использовать http://doc.qt.io/qt-5/qml-qtgraphicaleffects-desaturate.html – GrecKo

ответ

1

Увидев, как QtQuick работает над движком Javascript, я бы сказал, что невозможно сделать что-нибудь в QML, не прибегая к Javascript.

Чтобы настроить насыщенность, вам нужно будет преобразовать RGB в цвет HSL, а затем вернуться к RGB. QML имеет Qt.hsla() для последнего, но в последний раз я проверил это не обеспечивает преобразование из RGB в HSL, так что я в конечном итоге с помощью этого:

function rgbToHsl(r, g, b) { 
    r /= 255 
    g /= 255 
    b /= 255 
    var max = Math.max(r, g, b), min = Math.min(r, g, b) 
    var h, s, l = (max + min)/2 
    if (max == min) { 
    h = s = 0 
    } else { 
    var d = max - min 
    s = l > 0.5 ? d/(2 - max - min) : d/(max + min) 
    switch (max) { 
    case r: 
     h = (g - b)/d + (g < b ? 6 : 0) 
     break 
    case g: 
     h = (b - r)/d + 2 
     break 
    case b: 
     h = (r - g)/d + 4 
     break 
    } 
    h /= 6; 
    } 
    return {"h":h, "s":s, "l":l}; 
} 

Так вы в основном:

var ic = yourRGBColor.toString() 
var r = parseInt(ic.substr(1, 2), 16) 
var g = parseInt(ic.substr(3, 2), 16) 
var b = parseInt(ic.substr(5, 2), 16) 
var hsl = rgbToHsl(r, g, b) 
hsl.s *= .5 // desaturate 50% 
yourRGBColor = Qt.hsla(hsl.h, hsl.s, hsl.l, 1) 
1
function desaturate(colorString) 
{ 
    var c = Qt.darker(colorString, 1.0); 
    return Qt.hsla(c.hslHue, 0.0, c.hslLightness, c.a); 
} 
1

Просто измените цвет hsvSaturation, или hslSaturation, в зависимости от вашего color model.

Пример Test.qml, что де-насыщает синий прямоугольник постепенно каждый второй (работает с qmlscene Test.qml):

import QtQuick 2.7 
Item { 
    width: 100 
    height: 100 
    Rectangle { 
     anchors.fill: parent 
     objectName: "precious" 
     color: "#0000FF" 
     Timer { 
      running: true 
      repeat: true 
      onTriggered: parent.color.hslSaturation *= 0.8; 
     } 
    } 
} 

Скрытые в большом количестве текста, между двумя блоками кода, эти свойства фактически описаны в color QML Basic Type. Кажется, что они соответствуют версиям свойств цветных компонентов qreal в C++ (имена заканчиваются на ...F()).


Как @dtech государств, onTriggered:... юридически уже линия JavaScript. Если нужно, вы также можете перейти по строке на C++, найти атрибут элемента и изменить там свойство.

Пример main.cpp, показывающий выше Test.qml, который начинается с уже очень де-насыщенных (чисто в C++) синего прямоугольника, а затем постепенно де-насыщающих его (все еще сделано в QML/JavaScript):

#include <QGuiApplication> 
#include <QQuickView> 
#include <QQuickItem> 

int main(int argc, char *argv[]) 
{ 
    QGuiApplication app(argc, argv); 
    QQuickView view(QUrl(QLatin1String("qrc:/Test.qml"))); 
    view.show(); 
    if (QObject * rectangle = view.rootObject()->findChild<QObject*>("precious")) 
    { 
     qreal h, s, l, a; 
     rectangle->property("color").value<QColor>().getHslF(&h, &s, &l, &a); 
     s *= 0.2; 
     rectangle->setProperty("color", QVariant::fromValue(QColor::fromHsvF(h, s, l, a))); 
    } 
    return app.exec(); 
} 

Теперь вы можете удалить видимую строку JavaScript с Test.qml.


Обратите внимание, что я демонстрирую очень грубую цветную анимацию. Есть специальный инструмент ColorAnimation, чтобы сделать лучше.

Смежные вопросы