def redraw(self): self.graphicsScene.clear() # draw screenshot self.graphicsScene.addPixmap(self.screenPixel) # prepare for drawing selected area rect = QRectF(self.selectedArea) rect = rect.normalized() topLeftPoint = rect.topLeft() topRightPoint = rect.topRight() bottomLeftPoint = rect.bottomLeft() bottomRightPoint = rect.bottomRight() topMiddlePoint = (topLeftPoint + topRightPoint) / 2 leftMiddlePoint = (topLeftPoint + bottomLeftPoint) / 2 bottomMiddlePoint = (bottomLeftPoint + bottomRightPoint) / 2 rightMiddlePoint = (topRightPoint + bottomRightPoint) / 2 # draw the picture mask mask = QColor(0, 0, 0, 155) if self.selectedArea == QRect(): self.graphicsScene.addRect(0, 0, self.screenPixel.width(), self.screenPixel.height(), QPen(Qt.NoPen), mask) else: self.graphicsScene.addRect(0, 0, self.screenPixel.width(), topRightPoint.y(), QPen(Qt.NoPen), mask) self.graphicsScene.addRect(0, topLeftPoint.y(), topLeftPoint.x(), rect.height(), QPen(Qt.NoPen), mask) self.graphicsScene.addRect( topRightPoint.x(), topRightPoint.y(), self.screenPixel.width() - topRightPoint.x(), rect.height(), QPen(Qt.NoPen), mask) self.graphicsScene.addRect( 0, bottomLeftPoint.y(), self.screenPixel.width(), self.screenPixel.height() - bottomLeftPoint.y(), QPen(Qt.NoPen), mask) # draw the toolBar if self.action != ACTION_SELECT: spacing = 5 # show the toolbar first, then move it to the correct position # because the width of it may be wrong if this is the first time it shows self.tooBar.show() dest = QPointF(rect.bottomRight() - QPointF(self.tooBar.width(), 0) - QPointF(spacing, -spacing)) if dest.x() < spacing: dest.setX(spacing) pen_set_bar_height = self.penSetBar.height( ) if self.penSetBar is not None else 0 if dest.y() + self.tooBar.height( ) + pen_set_bar_height >= self.height(): if rect.top() - self.tooBar.height( ) - pen_set_bar_height < spacing: dest.setY(rect.top() + spacing) else: dest.setY(rect.top() - self.tooBar.height() - pen_set_bar_height - spacing) self.tooBar.move(self.mapToGlobal(dest.toPoint())) if self.penSetBar is not None: self.penSetBar.show() _pen_point = QPoint(dest.toPoint() + QPoint(0, self.tooBar.height() + spacing)) self.penSetBar.move(self.mapToGlobal(_pen_point)) if self.action == ACTION_TEXT: self.penSetBar.showFontWidget() else: self.penSetBar.showPenWidget() else: self.tooBar.hide() if self.penSetBar is not None: self.penSetBar.hide() # draw the list for step in self.drawListResult: self.drawOneStep(step) if self.drawListProcess is not None: self.drawOneStep(self.drawListProcess) if self.action != ACTION_TEXT: self.drawListProcess = None # if self.selectedArea != QRect(): # self.itemsToRemove = [] # # draw the selected rectangle # pen = QPen(QColor(0, 255, 255), 2) # self.itemsToRemove.append(self.graphicsScene.addRect(rect, pen)) # # draw the drag point # radius = QPoint(3, 3) # brush = QBrush(QColor(0, 255, 255)) # self.itemsToRemove.append( # self.graphicsScene.addEllipse(QRectF(topLeftPoint - radius, topLeftPoint + radius), pen, brush)) # self.itemsToRemove.append( # self.graphicsScene.addEllipse(QRectF(topMiddlePoint - radius, topMiddlePoint + radius), pen, brush)) # self.itemsToRemove.append( # self.graphicsScene.addEllipse(QRectF(topRightPoint - radius, topRightPoint + radius), pen, brush)) # self.itemsToRemove.append( # self.graphicsScene.addEllipse(QRectF(leftMiddlePoint - radius, leftMiddlePoint + radius), pen, brush)) # self.itemsToRemove.append( # self.graphicsScene.addEllipse(QRectF(rightMiddlePoint - radius, rightMiddlePoint + radius), pen, brush)) # self.itemsToRemove.append( # self.graphicsScene.addEllipse(QRectF(bottomLeftPoint - radius, bottomLeftPoint + radius), pen, brush)) # self.itemsToRemove.append( # self.graphicsScene.addEllipse(QRectF(bottomMiddlePoint - radius, bottomMiddlePoint + radius), pen, brush)) # self.itemsToRemove.append( # self.graphicsScene.addEllipse(QRectF(bottomRightPoint - radius, bottomRightPoint + radius), pen, brush)) # draw the textedit if self.textPosition is not None: textSpacing = 50 position = QPoint() if self.textPosition.x() + self.textInput.width( ) >= self.screenPixel.width(): position.setX(self.textPosition.x() - self.textInput.width()) else: position.setX(self.textPosition.x()) if self.textRect is not None: if self.textPosition.y() + self.textInput.height( ) + self.textRect.height() >= self.screenPixel.height(): position.setY(self.textPosition.y() - self.textInput.height() - self.textRect.height()) else: position.setY(self.textPosition.y() + self.textRect.height()) else: if self.textPosition.y() + self.textInput.height( ) >= self.screenPixel.height(): position.setY(self.textPosition.y() - self.textInput.height()) else: position.setY(self.textPosition.y()) self.textInput.move(self.mapToGlobal(position)) self.textInput.show() # self.textInput.getFocus() # draw the magnifier if self.action == ACTION_SELECT: self.drawMagnifier() if self.mousePressed: self.drawSizeInfo() if self.action == ACTION_MOVE_SELECTED: self.drawSizeInfo()
def drawOneStep(self, step): """ :type step: tuple """ if step[0] == ACTION_RECT: self.graphicsScene.addRect( QRectF(QPointF(step[1], step[2]), QPointF(step[3], step[4])), step[5]) elif step[0] == ACTION_ELLIPSE: self.graphicsScene.addEllipse( QRectF(QPointF(step[1], step[2]), QPointF(step[3], step[4])), step[5]) elif step[0] == ACTION_ARROW: arrow = QPolygonF() linex = float(step[1] - step[3]) liney = float(step[2] - step[4]) line = sqrt(pow(linex, 2) + pow(liney, 2)) # in case to divided by 0 if line == 0: return sinAngel = liney / line cosAngel = linex / line # sideLength is the length of bottom side of the body of an arrow # arrowSize is the size of the head of an arrow, left and right # sides' size is arrowSize, and the bottom side's size is arrowSize / 2 sideLength = step[5].width() arrowSize = 8 bottomSize = arrowSize / 2 tmpPoint = QPointF(step[3] + arrowSize * sideLength * cosAngel, step[4] + arrowSize * sideLength * sinAngel) point1 = QPointF(step[1] + sideLength * sinAngel, step[2] - sideLength * cosAngel) point2 = QPointF(step[1] - sideLength * sinAngel, step[2] + sideLength * cosAngel) point3 = QPointF(tmpPoint.x() - sideLength * sinAngel, tmpPoint.y() + sideLength * cosAngel) point4 = QPointF(tmpPoint.x() - bottomSize * sideLength * sinAngel, tmpPoint.y() + bottomSize * sideLength * cosAngel) point5 = QPointF(step[3], step[4]) point6 = QPointF(tmpPoint.x() + bottomSize * sideLength * sinAngel, tmpPoint.y() - bottomSize * sideLength * cosAngel) point7 = QPointF(tmpPoint.x() + sideLength * sinAngel, tmpPoint.y() - sideLength * cosAngel) arrow.append(point1) arrow.append(point2) arrow.append(point3) arrow.append(point4) arrow.append(point5) arrow.append(point6) arrow.append(point7) arrow.append(point1) self.graphicsScene.addPolygon(arrow, step[5], step[6]) elif step[0] == ACTION_LINE: self.graphicsScene.addLine( QLineF(QPointF(step[1], step[2]), QPointF(step[3], step[4])), step[5]) elif step[0] == ACTION_FREEPEN: self.graphicsScene.addPath(step[1], step[2]) elif step[0] == ACTION_TEXT: textAdd = self.graphicsScene.addSimpleText(step[1], step[2]) textAdd.setPos(step[3]) textAdd.setBrush(QBrush(step[4])) self.textRect = textAdd.boundingRect()
class Slider(QSlider, object): """ Custom slider that allows: - Left/Mid: Click to move handle - Ctrl and drag to move handle half velocity - Shift and drag to move handle quarter velocity - Ctrl + Shift and drag to move handle eighty velocity """ editingFinihsed = Signal() valueIncremented = Signal(object) floatValueChanged = Signal(object) def __init__(self, parent=None, dragger_steps=None, slider_range=None, *args, **kwargs): if dragger_steps is None: dragger_steps = INT_SLIDER_DRAG_STEPS if slider_range is None: slider_range = [-100, 100] super(Slider, self).__init__(parent=parent, **kwargs) self._slider_range = slider_range self._dragger_steps = dragger_steps self._is_float = False self._default_value = 0 self._prev_value = 0 self._delta_value = 0 self._start_drag_pos = QPointF() self._real_start_drag_pos = QPointF() self._draggers = None if dcc.is_maya(): self._left_button = Qt.MidButton self._mid_button = Qt.LeftButton else: self._left_button = Qt.LeftButton self._mid_button = Qt.MidButton self.setFocusPolicy(Qt.StrongFocus) self.setOrientation(Qt.Horizontal) self.setRange(self._slider_range[0], self._slider_range[1]) def mousePressEvent(self, event): self._prev_value = self.value() self._start_drag_pos = event.pos() if event.button() == Qt.MidButton: if not self._draggers: self._draggers = SliderDraggers(parent=self, is_float=self._is_float, dragger_steps=self._dragger_steps) self._draggers.increment.connect(self.valueIncremented.emit) self._draggers.show() if self._is_float: self._draggers.move( self.mapToGlobal(QPoint(event.pos().x() - 1, event.pos().y() - self._draggers.height() / 2))) else: draggers_height = self._draggers.height() self._draggers.move( self.mapToGlobal( QPoint(event.pos().x() - 1, event.pos().y() - (self._draggers.height() - draggers_height / 6)))) elif event.button() == self._left_button and event.modifiers() not in \ [Qt.ControlModifier, Qt.ShiftModifier, Qt.ControlModifier | Qt.ShiftModifier]: buttons = Qt.MouseButtons(self._mid_button) mouse_event = QMouseEvent(event.type(), event.pos(), self._mid_button, buttons, event.modifiers()) super(Slider, self).mousePressEvent(mouse_event) elif event.modifiers() in [Qt.ControlModifier, Qt.ShiftModifier, Qt.ControlModifier | Qt.ShiftModifier]: style_slider = QStyleOptionSlider() style_slider.initFrom(self) style_slider.orientation = self.orientation() available = self.style().pixelMetric(QStyle.PM_SliderSpaceAvailable, style_slider, self) x_loc = QStyle.sliderPositionFromValue( self.minimum(), self.maximum(), super(Slider, self).value(), available) buttons = Qt.MouseButtons(self._mid_button) new_pos = QPointF() new_pos.setX(x_loc) mouse_event = QMouseEvent(event.type(), new_pos, self._mid_button, buttons, event.modifiers()) self._start_drag_pos = new_pos self._real_start_drag_pos = event.pos() super(Slider, self).mousePressEvent(mouse_event) self._delta_value = self.value() - self._prev_value self.setValue(self._prev_value) else: super(Slider, self).mousePressEvent(event) def mouseMoveEvent(self, event): delta_x = event.pos().x() - self._real_start_drag_pos.x() delta_y = event.pos().y() - self._real_start_drag_pos.y() new_pos = QPointF() if event.modifiers() in [Qt.ControlModifier, Qt.ShiftModifier, Qt.ControlModifier | Qt.ShiftModifier]: if event.modifiers() == Qt.ControlModifier: new_pos.setX(self.startDragpos.x() + delta_x / 2) new_pos.setY(self.startDragpos.y() + delta_y / 2) elif event.modifiers() == Qt.ShiftModifier: new_pos.setX(self.startDragpos.x() + delta_x / 4) new_pos.setY(self.startDragpos.y() + delta_y / 4) elif event.modifiers() == Qt.ControlModifier | Qt.ShiftModifier: new_pos.setX(self.startDragpos.x() + delta_x / 8) new_pos.setY(self.startDragpos.y() + delta_y / 8) mouse_event = QMouseEvent(event.type(), new_pos, event.button(), event.buttons(), event.modifiers()) super(Slider, self).mouseMoveEvent(mouse_event) self.setValue(self.value() - self._delta_value) else: super(Slider, self).mouseMoveEvent(event) def keyPressEvent(self, event): p = self.mapFromGlobal(QCursor.pos()) self._start_drag_pos = p self._real_start_drag_pos = p self._default_value = 0 super(Slider, self).keyPressEvent(event) def wheelEvent(self, event): if not self.hasFocus(): event.ignore() else: super(Slider, self).wheelEvent(event) @property def slider_range(self): return self._slider_range