#qt #colors #qml #qtquick2 #hsl
#qt #Цвет #qml #qtquick2 #hsl
Вопрос:
Используя QtQuick, можно ли взять существующий цвет, определенный RGB, и обесцветить его, не прибегая к Javascript?
Комментарии:
1. Если вы просто хотите уменьшить насыщенность чего-либо на экране, вы можете использовать doc.qt.io/qt-5/qml-qtgraphicaleffects-desaturate.html
Ответ №1:
function desaturate(colorString)
{
let c = Qt.darker(colorString, 1.0);
return Qt.hsla(c.hslHue, 0.0, c.hslLightness, c.a);
}
Комментарии:
1.
Qt.darker
Действительно ли это единственный способ получить тип цвета из строки в JS?2. Ну, вы могли бы использовать
Qt.lighter
😉
Ответ №2:
Видя, как 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)
Ответ №3:
Просто измените цвет hsvSaturation
или hslSaturation
свойство в зависимости от вашей цветовой модели.
Пример 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( amp;h, amp;s, amp;l, amp;a );
s *= 0.2;
rectangle->setProperty( "color", QVariant::fromValue(QColor::fromHsvF( h, s, l, a )) );
}
return app.exec();
}
Теперь вы можете удалить видимую строку JavaScript из Test.qml
.
Обратите внимание, что я демонстрирую очень грубую цветовую анимацию. Существует специальный ColorAnimation
инструмент для улучшения.