Canvas memory leak
-
Hello everyone,
I'm encountering a memory leak issue in my QML UI when using a Canvas element combined with MouseArea to render a dynamic glowing effect on hover. I've tried multiple optimization techniques but the problem persists — memory usage keeps increasing over time and is never released, especially when moving the mouse over the element repeatedly.
Here’s a simplified version of my setup:
Rectangle { id: glowRect1 width: parent.width <= 470 ? 453 : 220 height: 220 color: "black" border.color: "#282928" border.width: 2 clip: true z: 2 Image { source: "assets/images/par_black2.png" width: 100 height: 100 y: 20 x: 15 z: 2 } Text { id: box_1 color: "white" text: qsTr("Параметры очистки") font.pixelSize: 18 font.bold: true font.family: cleanerFont.name y: 130 x: 15 z: 5 } Text { id: box_1_gray color: "gray" text: qsTr("Конфигурация и настройка\nпараметров очистки") font.pixelSize: 13 font.bold: false font.family: cleanerFont.name y: 155 x: 15 z: 5 } Canvas { id: gradientCanvas anchors.fill: parent z: 5 visible: glowArea1.containsMouse && !glowArea1.pressed && !parametersDialog.visible onPaint: { const ctx = getContext("2d"); ctx.clearRect(0, 0, width, height); if (!visible) return; const gradient = ctx.createRadialGradient( glowArea1.mouseX, glowArea1.mouseY, 0, glowArea1.mouseX, glowArea1.mouseY, Math.max(width, height) / 2 ); gradient.addColorStop(0, "gold"); gradient.addColorStop(1, "transparent"); ctx.strokeStyle = gradient; ctx.lineWidth = 3; ctx.strokeRect(1, 1, width - 2, height - 2); } Component.onCompleted: requestPaint() onVisibleChanged: if (visible) requestPaint() } Canvas { id: glowCircle1 width: 100 height: 100 visible: glowArea1.containsMouse && !glowArea1.pressed && !parametersDialog.visible z: 0 x: Math.max(-width / 2, Math.min(glowArea1.mouseX - width / 2, glowArea1.width - width / 2)) y: Math.max(-height / 2, Math.min(glowArea1.mouseY - height / 2, glowArea1.height - height / 2)) onPaint: { if (!visible) return; const ctx = getContext("2d"); ctx.clearRect(0, 0, width, height); const gradient = ctx.createRadialGradient( width / 2, height / 2, 0, width / 2, height / 2, 50 ); gradient.addColorStop(0.0, "rgba(9, 144, 30, 0.8)"); gradient.addColorStop(1.0, "rgba(0, 0, 0, 0.8)"); ctx.fillStyle = gradient; ctx.beginPath(); ctx.arc(width / 2, height / 2, 50, 0, Math.PI * 2); ctx.closePath(); ctx.fill(); } onVisibleChanged: if (visible) requestPaint() } MouseArea { id: glowArea1 anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: { main_window.isOverlayVisible = true; parametersDialog.open(); } z: 4 onPositionChanged: { gradientCanvas.requestPaint(); } onEntered: { if (!pressed && !parametersDialog.visible) { glowCircle1.visible = true; } gradientCanvas.requestPaint(); } onExited: { glowCircle1.visible = false; gradientCanvas.requestPaint(); } onPressed: { glowCircle1.visible = false; gradientCanvas.requestPaint(); } onReleased: { if (containsMouse && !parametersDialog.visible) { glowCircle1.visible = true; } gradientCanvas.requestPaint(); } onPressedChanged: { gradientCanvas.requestPaint(); } onContainsMouseChanged: { gradientCanvas.requestPaint(); } } } } }
-
Please create a bugreport over at https://bugreports.qt.io