Я создаю собственный стиль в QML и хотел бы иметь неопределенный индикатор выполнения, который выглядит следующим образом: закругленный фон с закругленной полосой внутри, которая перемещается слева направо.
У меня проблема с поведением, когда полоска доходит до конца. Использование только свойства clip приводит к тому, что закругленный стержень становится квадратным при контакте с краем.
Rectangle {
id: bg
color: "black"
width: 120; height: 8; radius: 4; x: 100; y: 50
clip: true
Rectangle {
id: bar
color: "orange"
width: 60; height: 8; radius: 4
NumberAnimation on x {
running: true
from: -(bar.width * 1.2 )
to: bg.width * 1.2
loops: Animation.Infinite
duration: 1000
}
}
}
Это связано с тем, что clip использует ограничивающий прямоугольник родительского объекта. Справедливо.
Затем я попытался использовать MultiEffect (я использую Qt6, поэтому нет OpacityMask) для применения к панели, однако после некоторых экспериментов я обнаружил, что свойства маскировки MultiEffect не учитывают положение MaskSource, поэтому это не сработало. работа.
MultiEffect {
source: bar
anchors.fill: bar
maskEnabled: true
maskSource: bg
}
Как мне добиться желаемого поведения, т. е. обрезать полосу фоном с закругленными углами?
Я знаю, что могу добиться аналогичного эффекта, увеличивая и уменьшая ширину полосы на соответствующих краях, но я хотел бы избежать этого, если это возможно.





Во-первых, в Qt6 есть OpacityMask, но он находится под Qt5Compat.GraphicalEffects.
Второй момент: проблема решаема с помощью Qt6 MultiEffect. Проблема в том, что maskSource должен быть указан немного иначе, чем эквивалент OpacityMask, с необходимым Item для создания слоев.
Анимацию bar необходимо обновить, чтобы она содержала как черный фон, так и панель анимации.
[РЕДАКТИРОВАТЬ]
Для улучшения сглаживания давайте поместим (1) включим клип и радиус в source, (2) однако выключим сглаживание в maskSource.
Rectangle {
id: barWithBackground
width: 120; height: 8; x: 100; y: 50; radius: 4
clip: true
visible: false
color: "black"
Rectangle {
id: bar
color: "orange"
width: 60; height: 8; radius: 4
NumberAnimation on x {
running: true
from: -(bar.width * 1.2 )
to: barWithBackground.width * 1.2
loops: Animation.Infinite
duration: 1000
}
}
}
// OpacityMask
// Qt5.* from QtGraphicalEffects
// Qt6.* from Qt5Compat.GraphicalEffects
// OpacityMask {
// source: barWithBackground
// anchors.fill: barWithBackground
// maskSource: roundedRectangleMask
// }
// Since Qt6.5
MultiEffect {
source: barWithBackground
anchors.fill: barWithBackground
maskEnabled: true
maskSource: roundedRectangleMask
}
Item {
id: roundedRectangleMask
width: 120; height: 8
layer.enabled: true
visible: false
Rectangle {
color: "black"
width: 120; height: 8; radius: 4
antialiasing: false
}
}
@eejakobowski Я включил сглаживание в source и отключил сглаживание в maskSource. Думаю, это улучшит результат.
Великолепно, это сработало (с некоторыми изменениями, я отредактирую, когда очередь редактирования иссякнет). Похоже, что это полностью отключило сглаживание для затронутых объектов. Знаете ли вы, как его снова включить? Я не смог найти это путем быстрого поиска в Google