Whiteboard in qml
-
Hi guys, I am new to coding and qml, however, I have to submit a project that gives a whiteboard.
below is the code that is purely a qml view.
Canvas {
id: whiteboardCanvas
anchors.fill: parent
renderTarget: Canvas.Imageproperty int startX: 0 property int startY: 0 property int currentX: 0 property int currentY: 0 property var lines: [] property var undoStack: [[]] property var redoStack: [] property real pencilSize: 2.0 property bool isDrawing: true property color selectedColor: "black" property int gridSize: 20 property color gridColor: "lightgray" property bool showGrid: false property string strokeStyle: "solid" // Define strokeStyle property onPaint: { var ctx = getContext("2d"); ctx.clearRect(0, 0, width, height); for (var i = 0; i < whiteboardCanvas.lines.length; i++) { var item = whiteboardCanvas.lines[i]; ctx.beginPath(); ctx.moveTo(item.points[0].x, item.points[0].y); ctx.strokeStyle = item.color; ctx.lineWidth = item.pencilSize || whiteboardCanvas.pencilSize; // Set line dash based on stored style if (item.strokeStyle === "dotted") { ctx.setLineDash([3,3]); } else if (item.strokeStyle === "dashed") { ctx.setLineDash([10,5]); } else { ctx.setLineDash([]); } for (var j = 1; j < item.points.length; j++) { ctx.lineTo(item.points[j].x, item.points[j].y); } ctx.stroke(); } } MouseArea { anchors.fill: parent onPressed: { whiteboardCanvas.isDrawing = true; whiteboardCanvas.lines.push({ type: whiteboardCanvas.drawShapeType, color: whiteboardCanvas.selectedColor, points: [], pencilSize: whiteboardCanvas.pencilSize, strokeStyle: whiteboardCanvas.strokeStyle // Store stroke style }); whiteboardCanvas.lines[whiteboardCanvas.lines.length - 1].points.push({ x: mouseX, y: mouseY }); } onPositionChanged: { if (whiteboardCanvas.isDrawing && containsMouse) { whiteboardCanvas.lines[whiteboardCanvas.lines.length - 1].points.push({ x: mouseX, y: mouseY }); whiteboardCanvas.currentX = mouse.x; whiteboardCanvas.currentY = mouse.y; whiteboardCanvas.requestPaint(); } } onReleased: { whiteboardCanvas.isDrawing = false; whiteboardCanvas.undoStack.push(JSON.parse(JSON.stringify(whiteboardCanvas.lines))); whiteboardCanvas.redoStack = []; } } } /*-----------------Row Layout to create buttons that give desired functions to be performed over the whiteboard. Includes functional buttons like saving an Image, gridlines, color palette, undo and redo button. */ Row { x: 10 y: 0 width: 790 height: 44 spacing: 10 Image { id: saveImage source: "qrc:/diskette.png" width: 32 height: 32 MouseArea { hoverEnabled: true anchors.fill: parent onClicked: {captureAndSave();} onEntered: {tooltip.visible = true;} onExited: {tooltip.visible = false;} } ToolTip {id: tooltip;text: "Save";visible: false} } Image { id: pen source: "qrc:/paint.png" width: 32 height: 32 MouseArea { hoverEnabled: true anchors.fill: parent onClicked: { mainWindow.drawShapeType = "line"; } onEntered: {tooltip1.visible = true;} onExited: {tooltip1.visible = false;} } ToolTip {id: tooltip1;text: "Pen";visible: false} } Image { id: colorr source: "qrc:/color-wheel.png" width: 32 height: 32 MouseArea { hoverEnabled: true anchors.fill: parent onClicked: { colorDialog.open(); } onEntered: {tooltip2.visible = true;} onExited: {tooltip2.visible = false;} } ToolTip {id: tooltip2;text: "Color";visible: false} } Image { id: undo source: "qrc:/undo.png" width: 32 height: 32 MouseArea { hoverEnabled: true anchors.fill: parent onClicked: { if (whiteboardCanvas.undoStack.length >= 1) { whiteboardCanvas.redoStack.push(JSON.parse(JSON.stringify(whiteboardCanvas.lines))); whiteboardCanvas.lines = whiteboardCanvas.undoStack.pop(); whiteboardCanvas.requestPaint(); } } onEntered: {tooltip3.visible = true;} onExited: {tooltip3.visible = false;} } ToolTip {id: tooltip3;text: "Undo";visible: false} } Image { id: redo source: "qrc:/redo.png" width: 32 height: 32 MouseArea { hoverEnabled: true anchors.fill: parent onClicked: { if (whiteboardCanvas.redoStack.length > 0) { whiteboardCanvas.undoStack.push(JSON.parse(JSON.stringify(whiteboardCanvas.lines))); whiteboardCanvas.lines = whiteboardCanvas.redoStack.pop(); whiteboardCanvas.requestPaint(); } } onEntered: {tooltip4.visible = true;} onExited: {tooltip4.visible = false;} } ToolTip {id: tooltip4;text: "Redo";visible: false} } Image { id: grid source: "qrc:/layout.png" width: 32 height: 32 MouseArea { hoverEnabled: true anchors.fill: parent onClicked: { whiteboardCanvas.showGrid = !whiteboardCanvas.showGrid whiteboardCanvas.requestPaint(); } onEntered: {tooltip5.visible = true;} onExited: {tooltip5.visible = false;} } ToolTip {id: tooltip5;text: "Grid-lines";visible: false} } Image { source: "qrc:/border-style.png" sourceSize.width: 32; sourceSize.height: 32 MouseArea { anchors.fill: parent hoverEnabled: true onClicked: { strokeStyleComboBox.visible = !strokeStyleComboBox.visible; } onEntered: {tooltip6.visible = true;} onExited: {tooltip6.visible = false;} } ToolTip {id: tooltip6;text: "Strokes";visible: false} ComboBox { id: strokeStyleComboBox width: 80 model: ["Solid", "Dotted", "Dashed"] visible: false // Initially hide the ComboBox y: 40 // Adjust the position below the image onCurrentIndexChanged: { whiteboardCanvas.strokeStyle = ["solid", "dotted", "dashed"][currentIndex]; whiteboardCanvas.requestPaint(); } } } } //----------------------Implementing a clear board function to clear the whiteboard when needed. Image { id:clearBoard x: 751 y: 550 source: "qrc:/paint.png" width: 32 height: 32 anchors { right: parent.right bottom: parent.bottom margins: 10 } MouseArea { hoverEnabled: true anchors.fill: parent onClicked: { whiteboardCanvas.linesQueue = []; whiteboardCanvas.undoStack = [[]]; whiteboardCanvas.redoStack = []; whiteboardCanvas.requestPaint(); } onEntered: {tooltip8.visible = true;} onExited: {tooltip8.visible = false;} } ToolTip {id: tooltip8;text: "Clear Whiteboard";visible: false} } //---------------Function that enables the user to save their file on the system. File type is default to png. function captureAndSave() { var timestamp = new Date().toISOString().replace(/[-:.]/g, ''); var filePath = "C:\\Users\\ashro\\whiteboard" + timestamp + ".png"; whiteboardCanvas.grabToImage(function (result) { result.saveToFile(filePath); console.log("File saved at: " + filePath); }, Qt.size(mainWindow.width, mainWindow.height), Qt.rect(mainWindow.x, mainWindow.y, mainWindow.width, mainWindow.height)); } //--------------- A color Dialog that allows the user to select from their desired color type using the palette. ColorDialog { id: colorDialog title: "Choose Color" onAccepted: { whiteboardCanvas.selectedColor = colorDialog.color; whiteboardCanvas.requestPaint(); } }
}
I need all your help as this is due tomorrow.
eventually,
firstly, lines maintain their current style of drawing. However, all the lines I drew before even changing my strokestyle are still undergoing changes and changing their line style to the style that I select all the time, also after I have selected dotted lines or dashed lines, even if I am selecting solid lines and drawing them, i m not able to draw any solid lines, instead, the first pair of lines that I drew first are changing to solid style.
Would be grateful if people can help me with this issue. -
maybe this can help?https://github.com/lingchensanwen/WhiteBoard-on-Qt
-
@Ronel_qtmaster
I did check this out previously, but then the team demands a pure qml view of the project, hence I have not planned to use QWidget in the program.The only problem with the code that I am facing is regarding the stroke style of the lines. It gives the user the ability to draw solid lines as soon as you launch the application. However if you shift to either of the two remaining stroke style and then shift back to solid stroke style, then you are not able to draw solid lines anymore.