You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt6 MultiEffect蒙版问题:自定义ProgressBar无法正确适配圆角蒙版

Qt Quick自定义ProgressBar蒙版适配问题解决方案

我想要自定义一个ProgressBar,目标外观如下:
目标进度条外观

需要裁剪内部的「浅橙色」矩形,使其适配橙色圆角背景。我使用MultiEffect来实现,但无法正确设置蒙版。背景Rectangle的radius为70,当前内容项的MultiEffect代码如下:

Item {
    id: contentRect

    Rectangle {
        id: progressRectangle
        // z: parent.z + 1
        color: DefaultStyle.grey_0
        width: mainItem.barWidth
        height: parent.height
        opacity: 0.5
        visible: false
    }
    MultiEffect {
        anchors.fill: progressRectangle
        source: progressRectangle
        maskThresholdMin: 0.5
        maskSpreadAtMin: 1.0
        maskEnabled: true
        maskSource: mask
        // opacity: 0.5
    }
    Item {
        id: mask
        layer.enabled: true
        layer.smooth: true
        visible: false
        width: contentRect.width
        height: contentRect.height
        Rectangle {
            width: contentRect.width
            height: contentRect.height
            radius: Math.round(70 * DefaultStyle.dp)
            color: "black"
        }
    }

        ...

}

已确认蒙版尺寸正确:
蒙版尺寸

但根据文档说明:

如果maskSource与source尺寸不同,maskSource图像会被拉伸以匹配source尺寸。

由于内部矩形的尺寸会随进度条的百分比变化,导致蒙版随内部Rectangle尺寸变化而变形,效果如下:
低进度效果
高进度效果

不想使用Qt5Compatibility API调用Qt5 GraphicalEffects API,以下是解决方案:

核心思路

问题根源是蒙版被强制拉伸适配进度条的动态宽度,导致圆角形状变形。解决关键是让蒙版尺寸始终匹配背景容器的固定尺寸,而非进度条的动态宽度。

方法1:调整MultiEffect的适配逻辑

将MultiEffect的尺寸绑定到背景容器,通过sourceRect控制仅显示进度条的有效区域:

Item {
    id: contentRect
    // 绑定到背景容器的固定尺寸
    width: mainItem.backgroundWidth
    height: mainItem.backgroundHeight

    Rectangle {
        id: progressRectangle
        color: DefaultStyle.grey_0
        width: mainItem.barWidth // 随进度变化的宽度
        height: parent.height
        opacity: 0.5
        visible: false
    }

    MultiEffect {
        anchors.fill: contentRect // 匹配背景容器尺寸
        source: progressRectangle
        // 仅截取进度条的有效宽度区域
        sourceRect: Qt.rect(0, 0, mainItem.barWidth, contentRect.height)
        maskThresholdMin: 0.5
        maskSpreadAtMin: 1.0
        maskEnabled: true
        maskSource: mask
    }

    Item {
        id: mask
        layer.enabled: true
        layer.smooth: true
        visible: false
        width: contentRect.width // 保持背景容器尺寸
        height: contentRect.height
        Rectangle {
            width: parent.width
            height: parent.height
            radius: Math.round(70 * DefaultStyle.dp)
            color: "black"
        }
    }
}

方法2:使用原生layer.mask替代MultiEffect

Qt Quick的layer.mask可以直接为Item添加蒙版,逻辑更直观,无需额外的MultiEffect:

Item {
    id: contentRect
    width: mainItem.backgroundWidth
    height: mainItem.backgroundHeight

    Rectangle {
        id: progressRectangle
        color: DefaultStyle.grey_0
        width: mainItem.barWidth
        height: parent.height
        opacity: 0.5
        // 启用layer并设置蒙版
        layer.enabled: true
        layer.mask: Rectangle {
            width: contentRect.width // 匹配背景容器尺寸
            height: contentRect.height
            radius: Math.round(70 * DefaultStyle.dp)
            color: "white" // 白色区域保留,透明区域裁剪
        }
    }
}

效果说明

两种方法都能保证蒙版的圆角形状始终与背景一致,进度条宽度变化时,只会裁剪超出圆角的部分,不会导致蒙版变形。其中方法2更简洁,推荐优先使用。

内容的提问来源于stack exchange,提问作者gra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 22:00:12