code: def mouseReleaseEvent(self, ev):
      if ev.button() == Qt.RightButton:
          menu = self.menus[bool(self.selectedShapesCopy)]
          self.restoreCursor()
          if (
              not menu.exec_(self.mapToGlobal(ev.pos()))
              and self.selectedShapesCopy
          ):
              # Cancel the move by deleting the shadow copy.
              # self.selectedShapeCopy = None
              self.selectedShapesCopy = []
              self.repaint()
  
      elif ev.button() == Qt.LeftButton and self.selectedShapes:
          if self.selectedVertex():
              self.overrideCursor(CURSOR_POINT)
          else:
              self.overrideCursor(CURSOR_GRAB)
  
      elif ev.button() == Qt.LeftButton and not self.fourpoint:
          pos = self.transformPos(ev.pos())
          if self.drawing():
              self.handleDrawing(pos)
          else:
              # pan
              QApplication.restoreOverrideCursor()  # ?
  
      if self.movingShape and self.hShape:
          if self.hShape in self.shapes:
              index = self.shapes.index(self.hShape)
              if (
                  self.shapesBackups[-1][index].points
                  != self.shapes[index].points
              ):
                  self.storeShapes()
                  self.shapeMoved.emit()  # connect to updateBoxlist in PPOCRLabel.py
  
              self.movingShape = False
  
imports: import copy
  from PyQt5.QtCore import Qt, pyqtSignal, QPointF, QPoint
  from PyQt5.QtGui import QPainter, QBrush, QColor, QPixmap
  from PyQt5.QtWidgets import QWidget, QMenu, QApplication
  from libs.shape import Shape
  from libs.utils import distance
label_desc: Use image node_id 14 for calling the Canvas obj's underlying member method code with example usage: obj.mouseReleaseEvent(ev) without return types