text: import sys
  from os.path import basename
  from PyQt5.QtCore import QPoint, Qt, QRect
  from PyQt5.QtWidgets import QAction, QMainWindow, QApplication, QPushButton, QMenu, QFileDialog
  from PyQt5.QtGui import QPixmap, QImage, QPainter, QPen
  
  import SnippingTool
  
  
  class Menu(QMainWindow):
      COLORS = ['Red', 'Black', 'Blue', 'Green', 'Yellow']
      SIZES = [1, 3, 5, 7, 9, 11]
      default_title = "Snipping Tool"
  
      # numpy_image is the desired image we want to display given as a numpy array.
      def __init__(self, numpy_image=None, snip_number=None, start_position=(300, 300, 350, 250)):
          super().__init__()
  
          self.drawing = False
          self.brushSize = 3
          self.brushColor = Qt.red
          self.lastPoint = QPoint()
          self.total_snips = 0
          self.title = Menu.default_title
          
          # New snip
          new_snip_action = QAction('New', self)
          new_snip_action.setShortcut('Ctrl+N')
          new_snip_action.setStatusTip('Snip!')
          new_snip_action.triggered.connect(self.new_image_window)
  
          # Brush color
          brush_color_button = QPushButton("Brush Color")
          colorMenu = QMenu()
          for color in Menu.COLORS:
              colorMenu.addAction(color)
          brush_color_button.setMenu(colorMenu)
          colorMenu.triggered.connect(lambda action: change_brush_color(action.text()))
  
          # Brush Size
          brush_size_button = QPushButton("Brush Size")
          sizeMenu = QMenu()
          for size in Menu.SIZES:
              sizeMenu.addAction("{0}px".format(str(size)))
          brush_size_button.setMenu(sizeMenu)
          sizeMenu.triggered.connect(lambda action: change_brush_size(action.text()))
  
          # Save
          save_action = QAction('Save', self)
          save_action.setShortcut('Ctrl+S')
          save_action.setStatusTip('Save')
          save_action.triggered.connect(self.save_file)
  
          # Exit
          exit_window = QAction('Exit', self)
          exit_window.setShortcut('Ctrl+Q')
          exit_window.setStatusTip('Exit application')
          exit_window.triggered.connect(self.close)
  
          self.toolbar = self.addToolBar('Exit')
          self.toolbar.addAction(new_snip_action)
          self.toolbar.addAction(save_action)
          self.toolbar.addWidget(brush_color_button)
          self.toolbar.addWidget(brush_size_button)
          self.toolbar.addAction(exit_window)
  
          self.snippingTool = SnippingTool.SnippingWidget()
          self.setGeometry(*start_position)
  
          # From the second initialization, both arguments will be valid
          if numpy_image is not None and snip_number is not None:
              self.image = self.convert_numpy_img_to_qpixmap(numpy_image)
              self.change_and_set_title("Snip #{0}".format(snip_number))
          else:
              self.image = QPixmap("background.PNG")
              self.change_and_set_title(Menu.default_title)
  
          self.resize(self.image.width(), self.image.height() + self.toolbar.height())
          self.show()
  
          def change_brush_color(new_color):
              self.brushColor = eval("Qt.{0}".format(new_color.lower()))
  
          def change_brush_size(new_size):
              self.brushSize = int(''.join(filter(lambda x: x.isdigit(), new_size)))
  
      # snippingTool.start() will open a new window, so if this is the first snip, close the first window.
      def new_image_window(self):
          if self.snippingTool.background:
              self.close()
          self.total_snips += 1
          self.snippingTool.start()
  
      def save_file(self):
          file_path, name = QFileDialog.getSaveFileName(self, "Save file", self.title, "PNG Image file (*.png)")
          if file_path:
              self.image.save(file_path)
              self.change_and_set_title(basename(file_path))
              print(self.title, 'Saved')
  
      def change_and_set_title(self, new_title):
          self.title = new_title
          self.setWindowTitle(self.title)
  
      def paintEvent(self, event):
          painter = QPainter(self)
          rect = QRect(0,  self.toolbar.height(), self.image.width(), self.image.height())
          painter.drawPixmap(rect, self.image)
  
      def mousePressEvent(self, event):
          if event.button() == Qt.LeftButton:
              self.drawing = True
              self.lastPoint = event.pos() - QPoint(0, self.toolbar.height())
  
      def mouseMoveEvent(self, event):
          if event.buttons() and Qt.LeftButton and self.drawing:
              painter = QPainter(self.image)
              painter.setPen(QPen(self.brushColor, self.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
              painter.drawLine(self.lastPoint, event.pos() - QPoint(0, self.toolbar.height()))
              self.lastPoint = event.pos() - QPoint(0, self.toolbar.height())
              self.update()
  
      def mouseReleaseEvent(self, event):
          if event.button == Qt.LeftButton:
              self.drawing = False
  
      # TODO exit application when we exit all windows
      def closeEvent(self, event):
          event.accept()
  
      @staticmethod
      def convert_numpy_img_to_qpixmap(np_img):
          height, width, channel = np_img.shape
          bytesPerLine = 3 * width
          return QPixmap(QImage(np_img.data, width, height, bytesPerLine, QImage.Format_RGB888).rgbSwapped())
  
  
  if __name__ == '__main__':
      app = QApplication(sys.argv)
      mainMenu = Menu()
      sys.exit(app.exec_())
  