Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Whiteboard in qml
Qt 6.11 is out! See what's new in the release blog

Whiteboard in qml

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
3 Posts 2 Posters 425 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Ashish_Pathak
    wrote on last edited by
    #1

    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.Image

        property 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.

    1 Reply Last reply
    0
    • Ronel_qtmasterR Offline
      Ronel_qtmasterR Offline
      Ronel_qtmaster
      wrote on last edited by
      #2

      maybe this can help?https://github.com/lingchensanwen/WhiteBoard-on-Qt

      A 1 Reply Last reply
      0
      • Ronel_qtmasterR Ronel_qtmaster

        maybe this can help?https://github.com/lingchensanwen/WhiteBoard-on-Qt

        A Offline
        A Offline
        Ashish_Pathak
        wrote on last edited by
        #3

        @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.

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved