Reputation: 1
I installed labelImg on windows 10 with pip install labelimg
and tried using the Create RectBox tool, which caused it to crash:
Traceback (most recent call last):
File "C:\Users...", line 530, in paintEvent
p.drawLine(self.prev_point.x(), 0, self.prev_point.x(), self.pixmap.height())
TypeError: arguments did not match any overloaded call:
drawLine(self, QLineF): argument 1 has unexpected type 'float'
drawLine(self, QLine): argument 1 has unexpected type 'float'
drawLine(self, int, int, int, int): argument 1 has unexpected type 'float'
drawLine(self, QPoint, QPoint): argument 1 has unexpected type 'float'
drawLine(self, Union[QPointF, QPoint], Union[QPointF, QPoint]): argument 1 has unexpected type 'float'
I have tired this with python 3.7 and 3.10 with the same result.
I have also tried downloading the code directly from https://github.com/tzutalin/labelImg, but there are all sorts of errors
> python labelImg.py
Traceback (most recent call last):
File "C:\Users...\labelImg.py", line 29, in <module>
from libs.resources import *
ModuleNotFoundError: No module named 'libs.resources'
(There is a libs
folder, but no file named resources
under it)
After commenting out this import line, I got an assertion error:
...... line 47, in get_string
assert(string_id in self.id_to_message), "Missing string id : " + string_id
AssertionError: Missing string id : useDefaultLabel
Is there a version that works?
Upvotes: 0
Views: 1592
Reputation: 1
Switch from lines 518 - 532 of canvas.py in libs of labelimg
From:
if self.current is not None and len(self.line) == 2:
left_top = self.line[0]
right_bottom = self.line[1]
rect_width = right_bottom.x() - left_top.x()
rect_height = right_bottom.y() - left_top.y()
p.setPen(self.drawing_rect_color)
brush = QBrush(Qt.BDiagPattern)
p.setBrush(brush)
p.drawRect(int(left_top.x()), int(left_top.y()), rect_width, rect_height)
if self.drawing() and not self.prev_point.isNull() and not self.out_of_pixmap(self.prev_point):
p.setPen(QColor(0, 0, 0))
p.drawLine(int(self.prev_point.x()), 0, int(self.prev_point.x()), self.pixmap.height())
p.drawLine(0, int(self.prev_point.y()), self.pixmap.width(), int(self.prev_point.y()))
to:
if self.current is not None and len(self.line) == 2:
left_top = self.line[0]
right_bottom = self.line[1]
rect_width = int(right_bottom.x() - left_top.x()) # Convert to integer
rect_height = int(right_bottom.y() - left_top.y()) # Convert to integer
p.setPen(self.drawing_rect_color)
brush = QBrush(Qt.BDiagPattern)
p.setBrush(brush)
p.drawRect(int(left_top.x()), int(left_top.y()), rect_width, rect_height)
Upvotes: 0
Reputation: 1
I am a beginner coder. I am gonna get straight to the point how to fix the bug above. Simply get to the file of your path "File "C:\Users...", line 530, in paintEvent...". You will open file named "canvas.py". Replace all the codes in your recent file (I recommend you should have a copy of everything you change, just for back-up if everything is going too far) with the codes below:
canvas.py
try:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
except ImportError:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
# from PyQt4.QtOpenGL import *
from libs.shape import Shape
from libs.utils import distance
CURSOR_DEFAULT = Qt.ArrowCursor
CURSOR_POINT = Qt.PointingHandCursor
CURSOR_DRAW = Qt.CrossCursor
CURSOR_MOVE = Qt.ClosedHandCursor
CURSOR_GRAB = Qt.OpenHandCursor
# class Canvas(QGLWidget):
class Canvas(QWidget):
zoomRequest = pyqtSignal(int)
lightRequest = pyqtSignal(int)
scrollRequest = pyqtSignal(int, int)
newShape = pyqtSignal()
selectionChanged = pyqtSignal(bool)
shapeMoved = pyqtSignal()
drawingPolygon = pyqtSignal(bool)
CREATE, EDIT = list(range(2))
epsilon = 24.0
def __init__(self, *args, **kwargs):
super(Canvas, self).__init__(*args, **kwargs)
# Initialise local state.
self.mode = self.EDIT
self.shapes = []
self.current = None
self.selected_shape = None # save the selected shape here
self.selected_shape_copy = None
self.drawing_line_color = QColor(0, 0, 255)
self.drawing_rect_color = QColor(0, 0, 255)
self.line = Shape(line_color=self.drawing_line_color)
self.prev_point = QPointF()
self.offsets = QPointF(), QPointF()
self.scale = 1.0
self.overlay_color = None
self.label_font_size = 8
self.pixmap = QPixmap()
self.visible = {}
self._hide_background = False
self.hide_background = False
self.h_shape = None
self.h_vertex = None
self._painter = QPainter()
self._cursor = CURSOR_DEFAULT
# Menus:
self.menus = (QMenu(), QMenu())
# Set widget options.
self.setMouseTracking(True)
self.setFocusPolicy(Qt.WheelFocus)
self.verified = False
self.draw_square = False
# initialisation for panning
self.pan_initial_pos = QPoint()
def set_drawing_color(self, qcolor):
self.drawing_line_color = qcolor
self.drawing_rect_color = qcolor
def enterEvent(self, ev):
self.override_cursor(self._cursor)
def leaveEvent(self, ev):
self.restore_cursor()
def focusOutEvent(self, ev):
self.restore_cursor()
def isVisible(self, shape):
return self.visible.get(shape, True)
def drawing(self):
return self.mode == self.CREATE
def editing(self):
return self.mode == self.EDIT
def set_editing(self, value=True):
self.mode = self.EDIT if value else self.CREATE
if not value: # Create
self.un_highlight()
self.de_select_shape()
self.prev_point = QPointF()
self.repaint()
def un_highlight(self, shape=None):
if shape == None or shape == self.h_shape:
if self.h_shape:
self.h_shape.highlight_clear()
self.h_vertex = self.h_shape = None
def selected_vertex(self):
return self.h_vertex is not None
def mouseMoveEvent(self, ev):
"""Update line with last point and current coordinates."""
pos = self.transform_pos(ev.pos())
# Update coordinates in status bar if image is opened
window = self.parent().window()
if window.file_path is not None:
self.parent().window().label_coordinates.setText(
'X: %d; Y: %d' % (pos.x(), pos.y()))
# Polygon drawing.
if self.drawing():
self.override_cursor(CURSOR_DRAW)
if self.current:
# Display annotation width and height while drawing
current_width = abs(self.current[0].x() - pos.x())
current_height = abs(self.current[0].y() - pos.y())
self.parent().window().label_coordinates.setText(
'Width: %d, Height: %d / X: %d; Y: %d' % (current_width, current_height, pos.x(), pos.y()))
color = self.drawing_line_color
if self.out_of_pixmap(pos):
# Don't allow the user to draw outside the pixmap.
# Clip the coordinates to 0 or max,
# if they are outside the range [0, max]
size = self.pixmap.size()
clipped_x = min(max(0, pos.x()), size.width())
clipped_y = min(max(0, pos.y()), size.height())
pos = QPointF(clipped_x, clipped_y)
elif len(self.current) > 1 and self.close_enough(pos, self.current[0]):
# Attract line to starting point and colorise to alert the
# user:
pos = self.current[0]
color = self.current.line_color
self.override_cursor(CURSOR_POINT)
self.current.highlight_vertex(0, Shape.NEAR_VERTEX)
if self.draw_square:
init_pos = self.current[0]
min_x = init_pos.x()
min_y = init_pos.y()
min_size = min(abs(pos.x() - min_x), abs(pos.y() - min_y))
direction_x = -1 if pos.x() - min_x < 0 else 1
direction_y = -1 if pos.y() - min_y < 0 else 1
self.line[1] = QPointF(min_x + direction_x * min_size, min_y + direction_y * min_size)
else:
self.line[1] = pos
self.line.line_color = color
self.prev_point = QPointF()
self.current.highlight_clear()
else:
self.prev_point = pos
self.repaint()
return
# Polygon copy moving.
if Qt.RightButton & ev.buttons():
if self.selected_shape_copy and self.prev_point:
self.override_cursor(CURSOR_MOVE)
self.bounded_move_shape(self.selected_shape_copy, pos)
self.repaint()
elif self.selected_shape:
self.selected_shape_copy = self.selected_shape.copy()
self.repaint()
return
# Polygon/Vertex moving.
if Qt.LeftButton & ev.buttons():
if self.selected_vertex():
self.bounded_move_vertex(pos)
self.shapeMoved.emit()
self.repaint()
# Display annotation width and height while moving vertex
point1 = self.h_shape[1]
point3 = self.h_shape[3]
current_width = abs(point1.x() - point3.x())
current_height = abs(point1.y() - point3.y())
self.parent().window().label_coordinates.setText(
'Width: %d, Height: %d / X: %d; Y: %d' % (current_width, current_height, pos.x(), pos.y()))
elif self.selected_shape and self.prev_point:
self.override_cursor(CURSOR_MOVE)
self.bounded_move_shape(self.selected_shape, pos)
self.shapeMoved.emit()
self.repaint()
# Display annotation width and height while moving shape
point1 = self.selected_shape[1]
point3 = self.selected_shape[3]
current_width = abs(point1.x() - point3.x())
current_height = abs(point1.y() - point3.y())
self.parent().window().label_coordinates.setText(
'Width: %d, Height: %d / X: %d; Y: %d' % (current_width, current_height, pos.x(), pos.y()))
else:
# pan
delta = ev.pos() - self.pan_initial_pos
self.scrollRequest.emit(delta.x(), Qt.Horizontal)
self.scrollRequest.emit(delta.y(), Qt.Vertical)
self.update()
return
# Just hovering over the canvas, 2 possibilities:
# - Highlight shapes
# - Highlight vertex
# Update shape/vertex fill and tooltip value accordingly.
self.setToolTip("Image")
priority_list = self.shapes + ([self.selected_shape] if self.selected_shape else [])
for shape in reversed([s for s in priority_list if self.isVisible(s)]):
# Look for a nearby vertex to highlight. If that fails,
# check if we happen to be inside a shape.
index = shape.nearest_vertex(pos, self.epsilon)
if index is not None:
if self.selected_vertex():
self.h_shape.highlight_clear()
self.h_vertex, self.h_shape = index, shape
shape.highlight_vertex(index, shape.MOVE_VERTEX)
self.override_cursor(CURSOR_POINT)
self.setToolTip("Click & drag to move point")
self.setStatusTip(self.toolTip())
self.update()
break
elif shape.contains_point(pos):
if self.selected_vertex():
self.h_shape.highlight_clear()
self.h_vertex, self.h_shape = None, shape
self.setToolTip(
"Click & drag to move shape '%s'" % shape.label)
self.setStatusTip(self.toolTip())
self.override_cursor(CURSOR_GRAB)
self.update()
# Display annotation width and height while hovering inside
point1 = self.h_shape[1]
point3 = self.h_shape[3]
current_width = abs(point1.x() - point3.x())
current_height = abs(point1.y() - point3.y())
self.parent().window().label_coordinates.setText(
'Width: %d, Height: %d / X: %d; Y: %d' % (current_width, current_height, pos.x(), pos.y()))
break
else: # Nothing found, clear highlights, reset state.
if self.h_shape:
self.h_shape.highlight_clear()
self.update()
self.h_vertex, self.h_shape = None, None
self.override_cursor(CURSOR_DEFAULT)
def mousePressEvent(self, ev):
pos = self.transform_pos(ev.pos())
if ev.button() == Qt.LeftButton:
if self.drawing():
self.handle_drawing(pos)
else:
selection = self.select_shape_point(pos)
self.prev_point = pos
if selection is None:
# pan
QApplication.setOverrideCursor(QCursor(Qt.OpenHandCursor))
self.pan_initial_pos = ev.pos()
elif ev.button() == Qt.RightButton and self.editing():
self.select_shape_point(pos)
self.prev_point = pos
self.update()
def mouseReleaseEvent(self, ev):
if ev.button() == Qt.RightButton:
menu = self.menus[bool(self.selected_shape_copy)]
self.restore_cursor()
if not menu.exec_(self.mapToGlobal(ev.pos()))\
and self.selected_shape_copy:
# Cancel the move by deleting the shadow copy.
self.selected_shape_copy = None
self.repaint()
elif ev.button() == Qt.LeftButton and self.selected_shape:
if self.selected_vertex():
self.override_cursor(CURSOR_POINT)
else:
self.override_cursor(CURSOR_GRAB)
elif ev.button() == Qt.LeftButton:
pos = self.transform_pos(ev.pos())
if self.drawing():
self.handle_drawing(pos)
else:
# pan
QApplication.restoreOverrideCursor()
def end_move(self, copy=False):
assert self.selected_shape and self.selected_shape_copy
shape = self.selected_shape_copy
# del shape.fill_color
# del shape.line_color
if copy:
self.shapes.append(shape)
self.selected_shape.selected = False
self.selected_shape = shape
self.repaint()
else:
self.selected_shape.points = [p for p in shape.points]
self.selected_shape_copy = None
def hide_background_shapes(self, value):
self.hide_background = value
if self.selected_shape:
# Only hide other shapes if there is a current selection.
# Otherwise the user will not be able to select a shape.
self.set_hiding(True)
self.repaint()
def handle_drawing(self, pos):
if self.current and self.current.reach_max_points() is False:
init_pos = self.current[0]
min_x = init_pos.x()
min_y = init_pos.y()
target_pos = self.line[1]
max_x = target_pos.x()
max_y = target_pos.y()
self.current.add_point(QPointF(max_x, min_y))
self.current.add_point(target_pos)
self.current.add_point(QPointF(min_x, max_y))
self.finalise()
elif not self.out_of_pixmap(pos):
self.current = Shape()
self.current.add_point(pos)
self.line.points = [pos, pos]
self.set_hiding()
self.drawingPolygon.emit(True)
self.update()
def set_hiding(self, enable=True):
self._hide_background = self.hide_background if enable else False
def can_close_shape(self):
return self.drawing() and self.current and len(self.current) > 2
def mouseDoubleClickEvent(self, ev):
# We need at least 4 points here, since the mousePress handler
# adds an extra one before this handler is called.
if self.can_close_shape() and len(self.current) > 3:
self.current.pop_point()
self.finalise()
def select_shape(self, shape):
self.de_select_shape()
shape.selected = True
self.selected_shape = shape
self.set_hiding()
self.selectionChanged.emit(True)
self.update()
def select_shape_point(self, point):
"""Select the first shape created which contains this point."""
self.de_select_shape()
if self.selected_vertex(): # A vertex is marked for selection.
index, shape = self.h_vertex, self.h_shape
shape.highlight_vertex(index, shape.MOVE_VERTEX)
self.select_shape(shape)
return self.h_vertex
for shape in reversed(self.shapes):
if self.isVisible(shape) and shape.contains_point(point):
self.select_shape(shape)
self.calculate_offsets(shape, point)
return self.selected_shape
return None
def calculate_offsets(self, shape, point):
rect = shape.bounding_rect()
x1 = rect.x() - point.x()
y1 = rect.y() - point.y()
x2 = (rect.x() + rect.width()) - point.x()
y2 = (rect.y() + rect.height()) - point.y()
self.offsets = QPointF(x1, y1), QPointF(x2, y2)
def snap_point_to_canvas(self, x, y):
"""
Moves a point x,y to within the boundaries of the canvas.
:return: (x,y,snapped) where snapped is True if x or y were changed, False if not.
"""
if x < 0 or x > self.pixmap.width() or y < 0 or y > self.pixmap.height():
x = max(x, 0)
y = max(y, 0)
x = min(x, self.pixmap.width())
y = min(y, self.pixmap.height())
return x, y, True
return x, y, False
def bounded_move_vertex(self, pos):
index, shape = self.h_vertex, self.h_shape
point = shape[index]
if self.out_of_pixmap(pos):
size = self.pixmap.size()
clipped_x = min(max(0, pos.x()), size.width())
clipped_y = min(max(0, pos.y()), size.height())
pos = QPointF(clipped_x, clipped_y)
if self.draw_square:
opposite_point_index = (index + 2) % 4
opposite_point = shape[opposite_point_index]
min_size = min(abs(pos.x() - opposite_point.x()), abs(pos.y() - opposite_point.y()))
direction_x = -1 if pos.x() - opposite_point.x() < 0 else 1
direction_y = -1 if pos.y() - opposite_point.y() < 0 else 1
shift_pos = QPointF(opposite_point.x() + direction_x * min_size - point.x(),
opposite_point.y() + direction_y * min_size - point.y())
else:
shift_pos = pos - point
shape.move_vertex_by(index, shift_pos)
left_index = (index + 1) % 4
right_index = (index + 3) % 4
left_shift = None
right_shift = None
if index % 2 == 0:
right_shift = QPointF(shift_pos.x(), 0)
left_shift = QPointF(0, shift_pos.y())
else:
left_shift = QPointF(shift_pos.x(), 0)
right_shift = QPointF(0, shift_pos.y())
shape.move_vertex_by(right_index, right_shift)
shape.move_vertex_by(left_index, left_shift)
def bounded_move_shape(self, shape, pos):
if self.out_of_pixmap(pos):
return False # No need to move
o1 = pos + self.offsets[0]
if self.out_of_pixmap(o1):
pos -= QPointF(min(0, o1.x()), min(0, o1.y()))
o2 = pos + self.offsets[1]
if self.out_of_pixmap(o2):
pos += QPointF(min(0, self.pixmap.width() - o2.x()),
min(0, self.pixmap.height() - o2.y()))
# The next line tracks the new position of the cursor
# relative to the shape, but also results in making it
# a bit "shaky" when nearing the border and allows it to
# go outside of the shape's area for some reason. XXX
# self.calculateOffsets(self.selectedShape, pos)
dp = pos - self.prev_point
if dp:
shape.move_by(dp)
self.prev_point = pos
return True
return False
def de_select_shape(self):
if self.selected_shape:
self.selected_shape.selected = False
self.selected_shape = None
self.set_hiding(False)
self.selectionChanged.emit(False)
self.update()
def delete_selected(self):
if self.selected_shape:
shape = self.selected_shape
self.un_highlight(shape)
self.shapes.remove(self.selected_shape)
self.selected_shape = None
self.update()
return shape
def copy_selected_shape(self):
if self.selected_shape:
shape = self.selected_shape.copy()
self.de_select_shape()
self.shapes.append(shape)
shape.selected = True
self.selected_shape = shape
self.bounded_shift_shape(shape)
return shape
def bounded_shift_shape(self, shape):
# Try to move in one direction, and if it fails in another.
# Give up if both fail.
point = shape[0]
offset = QPointF(2.0, 2.0)
self.calculate_offsets(shape, point)
self.prev_point = point
if not self.bounded_move_shape(shape, point - offset):
self.bounded_move_shape(shape, point + offset)
def paintEvent(self, event):
if not self.pixmap:
return super(Canvas, self).paintEvent(event)
p = self._painter
p.begin(self)
p.setRenderHint(QPainter.Antialiasing)
p.setRenderHint(QPainter.HighQualityAntialiasing)
p.setRenderHint(QPainter.SmoothPixmapTransform)
p.scale(self.scale, self.scale)
p.translate(self.offset_to_center())
temp = self.pixmap
if self.overlay_color:
temp = QPixmap(self.pixmap)
painter = QPainter(temp)
painter.setCompositionMode(painter.CompositionMode_Overlay)
painter.fillRect(temp.rect(), self.overlay_color)
painter.end()
p.drawPixmap(0, 0, temp)
Shape.scale = self.scale
Shape.label_font_size = self.label_font_size
for shape in self.shapes:
if (shape.selected or not self._hide_background) and self.isVisible(shape):
shape.fill = shape.selected or shape == self.h_shape
shape.paint(p)
if self.current:
self.current.paint(p)
self.line.paint(p)
if self.selected_shape_copy:
self.selected_shape_copy.paint(p)
# Paint rect
if self.current is not None and len(self.line) == 2:
left_top = self.line[0]
right_bottom = self.line[1]
rect_width = right_bottom.x() - left_top.x()
rect_height = right_bottom.y() - left_top.y()
p.setPen(self.drawing_rect_color)
brush = QBrush(Qt.BDiagPattern)
p.setBrush(brush)
p.drawRect(int(left_top.x()), int(left_top.y()), int(rect_width), int(rect_height))
if self.drawing() and not self.prev_point.isNull() and not self.out_of_pixmap(self.prev_point):
p.setPen(QColor(0, 0, 0))
p.drawLine(int(self.prev_point.x()), 0, int(self.prev_point.x()), int(self.pixmap.height()))
p.drawLine(0, int(self.prev_point.y()), int(self.pixmap.width()), int(self.prev_point.y()))
self.setAutoFillBackground(True)
if self.verified:
pal = self.palette()
pal.setColor(self.backgroundRole(), QColor(184, 239, 38, 128))
self.setPalette(pal)
else:
pal = self.palette()
pal.setColor(self.backgroundRole(), QColor(232, 232, 232, 255))
self.setPalette(pal)
p.end()
def transform_pos(self, point):
"""Convert from widget-logical coordinates to painter-logical coordinates."""
return point / self.scale - self.offset_to_center()
def offset_to_center(self):
s = self.scale
area = super(Canvas, self).size()
w, h = self.pixmap.width() * s, self.pixmap.height() * s
aw, ah = area.width(), area.height()
x = (aw - w) / (2 * s) if aw > w else 0
y = (ah - h) / (2 * s) if ah > h else 0
return QPointF(x, y)
def out_of_pixmap(self, p):
w, h = self.pixmap.width(), self.pixmap.height()
return not (0 <= p.x() <= w and 0 <= p.y() <= h)
def finalise(self):
assert self.current
if self.current.points[0] == self.current.points[-1]:
self.current = None
self.drawingPolygon.emit(False)
self.update()
return
self.current.close()
self.shapes.append(self.current)
self.current = None
self.set_hiding(False)
self.newShape.emit()
self.update()
def close_enough(self, p1, p2):
# d = distance(p1 - p2)
# m = (p1-p2).manhattanLength()
# print "d %.2f, m %d, %.2f" % (d, m, d - m)
return distance(p1 - p2) < self.epsilon
# These two, along with a call to adjustSize are required for the
# scroll area.
def sizeHint(self):
return self.minimumSizeHint()
def minimumSizeHint(self):
if self.pixmap:
return self.scale * self.pixmap.size()
return super(Canvas, self).minimumSizeHint()
def wheelEvent(self, ev):
qt_version = 4 if hasattr(ev, "delta") else 5
if qt_version == 4:
if ev.orientation() == Qt.Vertical:
v_delta = ev.delta()
h_delta = 0
else:
h_delta = ev.delta()
v_delta = 0
else:
delta = ev.angleDelta()
h_delta = delta.x()
v_delta = delta.y()
mods = ev.modifiers()
if int(Qt.ControlModifier) | int(Qt.ShiftModifier) == int(mods) and v_delta:
self.lightRequest.emit(v_delta)
elif Qt.ControlModifier == int(mods) and v_delta:
self.zoomRequest.emit(v_delta)
else:
v_delta and self.scrollRequest.emit(v_delta, Qt.Vertical)
h_delta and self.scrollRequest.emit(h_delta, Qt.Horizontal)
ev.accept()
def keyPressEvent(self, ev):
key = ev.key()
if key == Qt.Key_Escape and self.current:
print('ESC press')
self.current = None
self.drawingPolygon.emit(False)
self.update()
elif key == Qt.Key_Return and self.can_close_shape():
self.finalise()
elif key == Qt.Key_Left and self.selected_shape:
self.move_one_pixel('Left')
elif key == Qt.Key_Right and self.selected_shape:
self.move_one_pixel('Right')
elif key == Qt.Key_Up and self.selected_shape:
self.move_one_pixel('Up')
elif key == Qt.Key_Down and self.selected_shape:
self.move_one_pixel('Down')
def move_one_pixel(self, direction):
# print(self.selectedShape.points)
if direction == 'Left' and not self.move_out_of_bound(QPointF(-1.0, 0)):
# print("move Left one pixel")
self.selected_shape.points[0] += QPointF(-1.0, 0)
self.selected_shape.points[1] += QPointF(-1.0, 0)
self.selected_shape.points[2] += QPointF(-1.0, 0)
self.selected_shape.points[3] += QPointF(-1.0, 0)
elif direction == 'Right' and not self.move_out_of_bound(QPointF(1.0, 0)):
# print("move Right one pixel")
self.selected_shape.points[0] += QPointF(1.0, 0)
self.selected_shape.points[1] += QPointF(1.0, 0)
self.selected_shape.points[2] += QPointF(1.0, 0)
self.selected_shape.points[3] += QPointF(1.0, 0)
elif direction == 'Up' and not self.move_out_of_bound(QPointF(0, -1.0)):
# print("move Up one pixel")
self.selected_shape.points[0] += QPointF(0, -1.0)
self.selected_shape.points[1] += QPointF(0, -1.0)
self.selected_shape.points[2] += QPointF(0, -1.0)
self.selected_shape.points[3] += QPointF(0, -1.0)
elif direction == 'Down' and not self.move_out_of_bound(QPointF(0, 1.0)):
# print("move Down one pixel")
self.selected_shape.points[0] += QPointF(0, 1.0)
self.selected_shape.points[1] += QPointF(0, 1.0)
self.selected_shape.points[2] += QPointF(0, 1.0)
self.selected_shape.points[3] += QPointF(0, 1.0)
self.shapeMoved.emit()
self.repaint()
def move_out_of_bound(self, step):
points = [p1 + p2 for p1, p2 in zip(self.selected_shape.points, [step] * 4)]
return True in map(self.out_of_pixmap, points)
def set_last_label(self, text, line_color=None, fill_color=None):
assert text
self.shapes[-1].label = text
if line_color:
self.shapes[-1].line_color = line_color
if fill_color:
self.shapes[-1].fill_color = fill_color
return self.shapes[-1]
def undo_last_line(self):
assert self.shapes
self.current = self.shapes.pop()
self.current.set_open()
self.line.points = [self.current[-1], self.current[0]]
self.drawingPolygon.emit(True)
def reset_all_lines(self):
assert self.shapes
self.current = self.shapes.pop()
self.current.set_open()
self.line.points = [self.current[-1], self.current[0]]
self.drawingPolygon.emit(True)
self.current = None
self.drawingPolygon.emit(False)
self.update()
def load_pixmap(self, pixmap):
self.pixmap = pixmap
self.shapes = []
self.repaint()
def load_shapes(self, shapes):
self.shapes = list(shapes)
self.current = None
self.repaint()
def set_shape_visible(self, shape, value):
self.visible[shape] = value
self.repaint()
def current_cursor(self):
cursor = QApplication.overrideCursor()
if cursor is not None:
cursor = cursor.shape()
return cursor
def override_cursor(self, cursor):
self._cursor = cursor
if self.current_cursor() is None:
QApplication.setOverrideCursor(cursor)
else:
QApplication.changeOverrideCursor(cursor)
def restore_cursor(self):
QApplication.restoreOverrideCursor()
def reset_state(self):
self.de_select_shape()
self.un_highlight()
self.selected_shape_copy = None
self.restore_cursor()
self.pixmap = None
self.update()
def set_drawing_shape_to_square(self, status):
self.draw_square = status
End of code
Hope it help!
Upvotes: -1