Skip to content

[PyQt5] Make a simple drawing board through the program

I always want to try to use PyQt5 in Python to make a simple handwriting/drawing board, which can write and draw on the interface we develop at will.

That allows me to continue to develop many projects that I want to do, such as MNIST handwriting recognition.

So, today I started to try how to make a simple drawing board. After a lot of time, I finally got to rewrite those PyQt5 mouse-related methods.

If you are interested in learning PyQt5, you can read the PyQt5 teaching series I wrote: HERE.

If you want to refer the official tutorial: https://www.riverbankcomputing.com/static/Docs/PyQt5/index.html?highlight=qicon

The following will start to record how I made this simple drawing board.


drawing board design

We need to rewrite the following three methods in PyQt5:

  • mousePressEvent()
  • mouseMoveEvent()
  • mouseReleaseEvent()

This is our interface:


When the mouse is pressed, we record the start point position.


And then we record all the position of the mouse movement, draw each point into a graph, and end the drawing when the mouse is released.

Then store this trajectory from start point to end point in a List, if there are new points, add a new drawing track on top of the track of the existing List.


Code

# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *


class MainWindow(QWidget):
     def __init__(self):
         super(MainWindow, self).__init__()
         self.resize(500, 500)
         self.setWindowTitle('Painter Board')
         self.tracing_xy = []
         self.lineHistory = []
         self.pen = QPen(Qt.black, 10, Qt.SolidLine)

     def paintEvent(self, QPaintEvent):
         self.painter = QPainter()
         self.painter.begin(self)
         self.painter.setPen(self.pen)

         start_x_temp = 0
         start_y_temp = 0

         if self.lineHistory:
             for line_n in range(len(self.lineHistory)):
                 for point_n in range(1, len(self.lineHistory[line_n])):
                     start_x, start_y = self.lineHistory[line_n][point_n-1][0], self.lineHistory[line_n][point_n-1][1]
                     end_x, end_y = self.lineHistory[line_n][point_n][0], self.lineHistory[line_n][point_n][1]
                     self.painter.drawLine(start_x, start_y, end_x, end_y)

         for x, y in self.tracing_xy:
             if start_x_temp == 0 and start_y_temp == 0:
                 self.painter.drawLine(self.start_xy[0][0], self.start_xy[0][1], x, y)
             else:
                 self.painter.drawLine(start_x_temp, start_y_temp, x, y)

             start_x_temp = x
             start_y_temp = y

         self.painter.end()

     def mousePressEvent(self, QMouseEvent):
         self.start_xy = [(QMouseEvent.pos().x(), QMouseEvent.pos().y())]

     def mouseMoveEvent(self, QMouseEvent):
         self.tracing_xy.append((QMouseEvent.pos().x(), QMouseEvent.pos().y()))
         self.update()

     def mouseReleaseEvent(self, QMouseEvent):
         self.lineHistory.append(self.start_xy+self.tracing_xy)
         self.tracing_xy = []


if __name__ == '__main__':
     app = QApplication([])
     window = MainWindow()
     window.show()
     sys.exit(app.exec_())ㄘㄟ



The code is very short, you can test it.

Leave a Reply