def renderImage(self, remove_useless_background=False): if not self.Image: return paintedImage = QImage(self.Image.size(), QImage.Format_ARGB32) paintedImage.fill(Qt.transparent) painter = QPainter(paintedImage) if self.cropPolygon: painterPath = QPainterPath() painterPath.addPolygon(self.cropPolygon) painter.setClipPath(painterPath) painter.drawImage(QPoint(), self.Image) # draw polygon pen = QPen(self.PolygonEdgeColor, 5) painter.setPen(pen) if len(self.polygonList): for polygon in self.polygonList: # pp = QPolygonF([QPointF(point[0], point[1]) for point in polygon['geo']]) if polygon['selected']: painter.setBrush(self.PolygonSelectedColor) else: painter.setBrush(self.PolygonColor) painter.drawPolygon(polygon['geo']) painter.end() if remove_useless_background and self.cropPolygon: return paintedImage.copy(painterPath.boundingRect().toRect()) else: return paintedImage
def mouseMoveEvent(self, event): super(CBlueprintView, self).mouseMoveEvent(event) self.setTransformationAnchor(QGraphicsView.NoAnchor) pos = event.pos() if self.m_StartPos: offsetX, offsetY = pos.x() - self.m_StartPos.x(), pos.y( ) - self.m_StartPos.y() offsetX /= self.m_Scale offsetY /= self.m_Scale self.translate(offsetX, offsetY) self.m_StartPos = pos self.m_IsHasMove = True if self.m_SelectPos: rect = QRect(min(self.m_SelectPos.x(), pos.x()), min(self.m_SelectPos.y(), pos.y()), abs(self.m_SelectPos.x() - pos.x()), abs(self.m_SelectPos.y() - pos.y())) path = QPainterPath() path.addPolygon(self.mapToScene(rect)) path.closeSubpath() self.m_Scene.RubberBandSelecNodeUI(path, self.rubberBandSelectionMode(), self.viewportTransform()) self.m_RubberBand.setGeometry(rect)
def calc_path(self): path = QPainterPath(QPointF(self.pos_src[0], self.pos_src[1])) # 起点 path.lineTo(QPointF(self.pos_dst[0], self.pos_dst[1])) # 终点 if self.directed: # 画箭头 self.line = QLineF(QPointF(self.pos_src[0], self.pos_src[1]), QPointF(self.pos_dst[0], self.pos_dst[1])) if self.flag == 0: self.line.setLength(self.line.length() - 20) else: self.line.setLength(self.line.length() - self.edge_wrap.end_item.r) v = self.line.unitVector() v.setLength(20) v.translate(QPointF(self.line.dx(), self.line.dy())) n = v.normalVector() n.setLength(n.length() * 0.5) n2 = n.normalVector().normalVector() p1 = v.p2() p2 = n.p2() p3 = n2.p2() # 方法2 arrow = QPolygonF([p1, p2, p3, p1]) path.addPolygon(arrow) # path = QPainterPath(QPointF(self.pos_src[0], self.pos_src[1])) # path.lineTo(self.pos_dst[0], self.pos_dst[1]) return path
def shape(self, object): path = QPainterPath() if (not object.cell().isEmpty()): path.addRect(self.boundingRect(object)) else: x = object.shape() if x == MapObject.Rectangle: bounds = object.bounds() if (bounds.isNull()): path.addEllipse(bounds.topLeft(), 20, 20) else: path.addRoundedRect(bounds, 10, 10) elif x == MapObject.Polygon or x == MapObject.Polyline: pos = object.position() polygon = object.polygon().translated(pos) screenPolygon = self.pixelToScreenCoords_(polygon) if (object.shape() == MapObject.Polygon): path.addPolygon(screenPolygon) else: for i in range(1, screenPolygon.size()): path.addPolygon( self.lineToPolygon(screenPolygon[i - 1], screenPolygon[i])) path.setFillRule(Qt.WindingFill) elif x == MapObject.Ellipse: bounds = object.bounds() if (bounds.isNull()): path.addEllipse(bounds.topLeft(), 20, 20) else: path.addEllipse(bounds) return path
def __init__(self, parentItem, segments, colour): QGraphicsItem.__init__(self, parent=parentItem) self.colour_name = colour self.shape = QPainterPath() self.labels = QGraphicsItemGroup(self) self.bbox = QRectF(0, 0, 0, 0) for (p1, p2), label in segments: lvect = QVector2D(p2 - p1) lpath = QPainterPath() m = TWY_line_margin l = lvect.length() plst = [QPointF(-m, 0), QPointF(-m/3, -m), QPointF(l + m/3, -m), QPointF(l + m, 0), QPointF(l + m/3, m), QPointF(-m/3, m)] lpath.addPolygon(QPolygonF(plst)) lrot = QTransform() lrot.rotateRadians(atan2(lvect.y(), lvect.x())) lpath = lrot.map(lpath) lpath.translate(p1) self.shape.addPath(lpath) rect = QRectF(p1, p2).normalized() if label != None: self.labels.addToGroup(TaxiwayLabelItem(label, rect.center(), self)) self.bbox |= rect self.shape.setFillRule(Qt.WindingFill) self.mouse_highlight = False self.labels.setVisible(False)
def drawPolygonOnVideo(values, painter, surface, gt): ''' Draw Polygons on Video ''' poly = [] for pt in values: if hasElevationModel(): pt = GetLine3DIntersectionWithPlane( GetSensor(), pt, GetFrameCenter()[2]) scr_x, scr_y = vut.GetInverseMatrix( pt[1], pt[0], gt, surface) center = QPoint(scr_x, scr_y) poly.append(center) poly.append(poly[0]) radius = 3 polygon = QPolygonF(poly) pen = QPen() pen.setColor(Qt.green) pen.setWidth(radius) pen.setCapStyle(Qt.RoundCap) pen.setJoinStyle(Qt.RoundJoin) brush = QBrush() brush.setColor(QColor(176, 255, 128, 28)) brush.setStyle(Qt.SolidPattern) path = QPainterPath() path.addPolygon(polygon) painter.setPen(pen) painter.drawPolygon(polygon) painter.fillPath(path, brush) return
def paintStripe(self, st, p, coord, color): # left right if st == 0: left1 = QPoint(coord[0], coord[1] + self.grid_size // 2 - self.radius) left2 = QPoint(coord[0], coord[1] + self.grid_size // 2 + self.radius) right1 = QPoint(left1.x() + self.grid_size, left1.y()) right2 = QPoint(left2.x() + self.grid_size, left2.y()) poly = QPolygonF([left1, right1, right2, left2]) # top to bottom elif st == 1: top1 = QPoint(coord[0] + self.grid_size // 2 - self.radius, coord[1]) top2 = QPoint(coord[0] + self.grid_size // 2 + self.radius, coord[1]) bot1 = QPoint(top1.x(), top1.y() + self.grid_size) bot2 = QPoint(top2.x(), top2.y() + self.grid_size) poly = QPolygonF([top1, top2, bot2, bot1]) path = QPainterPath() path.addPolygon(poly) p.drawPolygon(poly) brush = QBrush() brush.setColor(color) brush.setStyle(Qt.SolidPattern) p.fillPath(path, brush)
def shape(self, object): path = QPainterPath() if (not object.cell().isEmpty()): path.addRect(self.boundingRect(object)) else: x = object.shape() if x==MapObject.Rectangle: bounds = object.bounds() if (bounds.isNull()): path.addEllipse(bounds.topLeft(), 20, 20) else: path.addRoundedRect(bounds, 10, 10) elif x==MapObject.Polygon or x==MapObject.Polyline: pos = object.position() polygon = object.polygon().translated(pos) screenPolygon = self.pixelToScreenCoords_(polygon) if (object.shape() == MapObject.Polygon): path.addPolygon(screenPolygon) else: for i in range(1, screenPolygon.size()): path.addPolygon(self.lineToPolygon(screenPolygon[i - 1], screenPolygon[i])) path.setFillRule(Qt.WindingFill) elif x==MapObject.Ellipse: bounds = object.bounds() if (bounds.isNull()): path.addEllipse(bounds.topLeft(), 20, 20) else: path.addEllipse(bounds) return path
def paintEvent(self, event): if self.display_status: super().paintEvent(event) painter = QPainter(self) painter_path = QPainterPath() qt_pen_1 = QPen(Qt.red, 2, Qt.SolidLine) qt_pen_2 = QPen(Qt.green, 10, Qt.SolidLine) qt_pen_3 = QPen(Qt.red, 2, Qt.DotLine) painter.setPen(qt_pen_1) painter.drawPolygon(QPolygon(self.roi_rect), Qt.WindingFill) painter_path.addPolygon(QPolygonF(self.roi_rect)) painter_path.closeSubpath() # qt_brush = QBrush(Qt.green) qt_brush = QBrush(QColor(0, 255, 0, 64)) painter.setBrush(qt_brush) painter.drawPath(painter_path) # painter.drawPoint(self.tmp_center_pt) painter.setPen(qt_pen_3) painter.drawLine(self.roi_rect[0], self.roi_rect[2]) painter.drawLine(self.roi_rect[1], self.roi_rect[3]) painter.setPen(qt_pen_2) for elem in self.roi_rect: painter.drawPoint(elem) # for elem in self.img_rect: # painter.drawPoint(elem) if self.default_rect: self.update()
def draw_polygons(self, event): if self.polygons: painter = QPainter(self) # painter.drawEllipse(0, 0, self.width()/2, self.width()/2) for (pa, pb, pc), color in self.polygons: a = QPoint(pa.x, pa.y) b = QPoint(pb.x, pb.y) c = QPoint(pc.x, pc.y) pen = QPen() if color: pen.setColor(color) else: pen.setColor(QColor(0, 0, 0)) painter.setPen(pen) polygon = QPolygonF([a, b, c]) painter.drawPolygon(polygon) if color: path = QPainterPath() path.addPolygon(polygon) # painter.setBrush(QBrush(color)) painter.fillPath(path, QBrush(color))
def shape(self): #path = super().shape() path = QPainterPath() #path.addRect(self.calcRect()) path.addPolygon(self.arrowHead) return path
def setupForDrawing(self): """ Create the QPolygon and the QPainterPath according to the blob's contours. """ # QPolygon to draw the blob #working with mask the center of the pixels is in 0, 0 #if drawing the center of the pixel is 0.5, 0.5 qpolygon = QPolygonF() for i in range(self.contour.shape[0]): qpolygon << QPointF(self.contour[i, 0] + 0.5, self.contour[i, 1] + 0.5) self.qpath = QPainterPath() self.qpath.addPolygon(qpolygon) for inner_contour in self.inner_contours: qpoly_inner = QPolygonF() for i in range(inner_contour.shape[0]): qpoly_inner << QPointF(inner_contour[i, 0], inner_contour[i, 1]) path_inner = QPainterPath() path_inner.addPolygon(qpoly_inner) self.qpath = self.qpath.subtracted(path_inner)
def FOV(self, Robo): view = QPainterPath() xPos = math.cos(math.radians(Robo.alpha + (Robo.FOV / 2))) * Robo.radius yPos = math.sin(math.radians(Robo.alpha + (Robo.FOV / 2))) * Robo.radius xPos2 = math.cos(math.radians(Robo.alpha - (Robo.FOV / 2))) * Robo.radius yPos2 = math.sin(math.radians(Robo.alpha - (Robo.FOV / 2))) * Robo.radius x1 = QPoint( int(round(Robo.position.x())) + Robo.radius, int(round(Robo.position.y())) + Robo.radius) x2 = x1 + QPoint( (int(round(Robo.position.x())) + Robo.radius) + 1000 * xPos, (int(round(Robo.position.y())) + Robo.radius) - 1000 * yPos) x3 = x1 + QPoint( (int(round(Robo.position.x())) + Robo.radius) + 1000 * xPos2, (int(round(Robo.position.y())) + Robo.radius) - 1000 * yPos2) view.addPolygon(QPolygonF([x1, x2, x3])) view.closeSubpath() return view
def painterPath(self): """ Returns the current shape as QPainterPath (used for collision detection). :rtype: QPainterPath """ path = QPainterPath() path.addPolygon(self.polygon) return path
def shape(self): """ Returns the shape of this item as a QPainterPath in local coordinates. :rtype: QPainterPath """ path = QPainterPath() path.addPolygon(self.polygon) return path
class Segment(QGraphicsItem): def __init__(self, color, offset, parent): super(Segment, self).__init__(parent) self.color = color # 每节的身体段 self.rect = QRectF(offset, -20, 30, 40) self.path = QPainterPath() self.path.addEllipse(self.rect) # 每节的左腿 x = offset + 15 y = -20 self.path.addPolygon( QPolygonF( [QPointF(x, y), QPointF(x - 5, y - 18), QPointF(x - 5, y)])) self.path.closeSubpath() # 每节的右腿 y = 20 self.path.addPolygon( QPolygonF( [QPointF(x, y), QPointF(x - 5, y + 18), QPointF(x - 5, y)])) self.path.closeSubpath() self.change = 1 self.angle = 0 def boundingRect(self): return self.path.boundingRect() def shape(self): return self.path def paint(self, painter, option, widget=None): painter.setPen(Qt.NoPen) painter.setBrush(QBrush(self.color)) if option.levelOfDetailFromTransform(self.transform()) < 0.9: painter.drawEllipse(self.rect) else: painter.drawPath(self.path) def advance(self, phase): if phase == 0: matrix = self.transform() matrix.reset() self.setTransform(matrix) self.angle += self.change * random.random() if self.angle > 6: self.change = -1 # self.angle -= 0.00001 elif self.angle < -6: self.change = 1 # self.angle += 0.00001 elif phase == 1: self.setRotation(self.angle)
def shape(self): path = QPainterPath() stroker = QPainterPathStroker() path.moveTo(self.line().p1()) path.lineTo(self.line().p2()) path.addPolygon(self._arrow_head) path.addPolygon(self._arrow_tail) stroker.setWidth(self.pen().width()) return stroker.createStroke(path)
def getPath(self) -> QPainterPath: pol = QPolygonF() pol.append(self._firstPoint) for p in self._midPoints: pol.append(p) pol.append(self._lastPoint) ans = QPainterPath() ans.addPolygon(pol) return ans
class Segment(QGraphicsItem): def __init__(self, color, offset, parent): super(Segment, self).__init__(parent) self.color = color self.rect = QRectF(offset, -20, 30, 40) self.path = QPainterPath() self.path.addEllipse(self.rect) x = offset + 15 y = -20 self.path.addPolygon( QPolygonF( [QPointF(x, y), QPointF(x - 5, y - 12), QPointF(x - 5, y)])) self.path.closeSubpath() y = 20 self.path.addPolygon( QPolygonF( [QPointF(x, y), QPointF(x - 5, y + 12), QPointF(x - 5, y)])) self.path.closeSubpath() self.change = 1 self.angle = 0 self.timer = QTimer() self.timer.timeout.connect(self.timeout) self.timer.start(INTERVAL) def boundingRect(self): return self.path.boundingRect() def shape(self): return self.path def paint(self, painter, option, widget=None): painter.setPen(Qt.NoPen) painter.setBrush(QBrush(self.color)) if option.levelOfDetailFromTransform(self.transform()) < 0.9: painter.drawEllipse(self.rect) else: painter.drawPath(self.path) def timeout(self): if not Running: return matrix = self.transform() matrix.reset() self.setTransform(matrix) self.angle += self.change * random.random() if self.angle > 4.5: self.change = -1 self.angle -= 0.00001 elif self.angle < -4.5: self.change = 1 self.angle += 0.00001 self.setRotation(self.angle)
def view_cone(self): path = QPainterPath() a = self.pos.toPointF() b = a + QPointF(5000 * math.cos(math.radians(self.alpha + self.aov)), 5000 * math.sin(math.radians(self.alpha + self.aov))) c = a + QPointF(5000 * math.cos(math.radians(self.alpha - self.aov)), 5000 * math.sin(math.radians(self.alpha - self.aov))) path.addPolygon(QPolygonF([a, b, c])) path.closeSubpath() return path
def shape(self): if self._stock_polygon == NodePolygon.Circle: path = super().shape() else: path = QPainterPath() path.addPolygon(self._node_polygon) label_path = QPainterPath() label_path.addRect(self._label_rect) return path.united(label_path)
def shape(self): """ Returns the shape of this item as a QPainterPath in local coordinates. :rtype: QPainterPath """ path = QPainterPath() path.addPolygon(self.polygon) for shape in self.handleBound: path.addEllipse(shape) return path
def pathForPointV1(self, point, scene, rsize=3): view = scene.views()[0] pc = view.mapFromScene(point) dp = QPoint(rsize, rsize) recv = QRect(pc - dp, pc + dp) poly = view.mapToScene(recv) path = QPainterPath() path.addPolygon(poly) path.closeSubpath() return path
def shape(self): """ Returns the shape of this item as a QPainterPath in local coordinates. """ path = QPainterPath() path.addPolygon(self.polygon) if self.isSelected(): for shape in self.handles.values(): path.addEllipse(shape) return path
def shape(self): #TODO: add proper path corresponding to bounding rect #has to be implemented, otherwise bounding rect is the assumed shape path = QPainterPath() polygon = QPolygonF() polygon.append(QPointF(Triangle.a/2, 0)) polygon.append(QPointF(0, Triangle.h)) polygon.append(QPointF(Triangle.a, Triangle.h)) polygon.append(QPointF(Triangle.a+Triangle.a/2, 0)) path.addPolygon(polygon) return path
def drawBody(self, qp): #画身体 path4 = QPainterPath() body_polygon = QPolygonF() body_polygon << QPointF(316.0, 349.0) << QPointF( 580.0, 349.0) << QPointF(577.0, 496.0) << QPointF(319.0, 496.0) # 绘制一个多边形 path4.addPolygon(body_polygon) path4.closeSubpath() qp.setBrush(QColor(156, 214, 239)) qp.drawPath(path4) #画肚子 path5 = QPainterPath() belly_width = 180.0 belly_length = 235.0 bellyre = QRectF(365.0, 240.0, belly_width, belly_length) belly_center_x = 365.0 + belly_width / 2 belly_center_y = 240.0 + belly_length / 2 path5.moveTo(belly_center_x, belly_center_y) path5.arcTo(bellyre, 180, 180) path5.closeSubpath() qp.setBrush(Qt.white) qp.drawPath(path5) #画围兜 path6 = QPainterPath() scarf_polygon = QPolygonF() scarf_polygon << QPointF(316.0, 349.0) << QPointF( 580.0, 349.0) << QPointF(450.0, 379.0) << QPointF(319.0, 349.0) path6.addPolygon(scarf_polygon) path6.closeSubpath() qp.setBrush(Qt.red) qp.drawPath(path6) #画铃铛 bell_re = QRectF(442.0, 364.0, 30, 30) qp.setBrush(QColor(250, 221, 81)) qp.drawEllipse(bell_re) qp.drawLine(455, 370, 465, 380) qp.drawLine(465, 380, 455, 385) #画口袋 path7 = QPainterPath() pocket_width = 112.0 pocket_length = 104.0 pocketre = QRectF(400.0, 352.0, pocket_width, pocket_length) pocket_center_x = 412.0 + pocket_width / 2 pocket_center_y = 352.0 + pocket_length / 2 path7.moveTo(pocket_center_x, pocket_center_y) path7.arcTo(pocketre, 180, 180) path7.closeSubpath() qp.setBrush(Qt.white) qp.drawPath(path7)
def updatePath(self): try: attrs = self.stackedWidget.currentWidget().get_attributes() attrs.keys() except Exception as e: msg = 'Tracking Lib. Attributes Error:\n{}'.format(e) self.generateCriticalMessage(msg) return if 'position' in attrs: self.trackingPathGroup.setPoints(self.currentFrameNo) if 'arrow' in attrs: for i, arrow_item in enumerate(self.item_dict['arrow']): begin = self.df['position'].loc[self.currentFrameNo, i].as_matrix() end = self.df['arrow'].loc[self.currentFrameNo, i].as_matrix() arrow_item.setPosition(begin, end) if 'path' in attrs: for path_item, path_data in zip(self.item_dict['path'], self.data_dict['path'][self.currentFrameNo]): poly = QPolygonF() for p in path_data: poly.append(QPointF(*p)) painter_path = QPainterPath() painter_path.addPolygon(poly) path_item.setPath(painter_path) pen = QPen(Qt.blue) pen.setWidth(2) path_item.setPen(pen) if 'polygon' in attrs: for path_item, path_data in zip(self.item_dict['polygon'], self.data_dict['polygon'][self.currentFrameNo]): poly = QPolygonF() for p in path_data: poly.append(QPointF(*p)) painter_path = QPainterPath() painter_path.addPolygon(poly) path_item.setPath(painter_path) pen = QPen(Qt.black) pen.setWidth(1) path_item.setPen(pen) if 'rect' in attrs: for rect_item, rect in zip(self.item_dict['rect'], self.data_dict['rect'][self.currentFrameNo]): rect_item.setRect(QRectF(QPointF(*rect[0]), QPointF(*rect[1])))
def updatePath(self): try: attrs = self.stackedWidget.currentWidget().get_attributes() attrs.keys() except Exception as e: msg = 'Tracking Lib. Attributes Error:\n{}'.format(e) self.generateCriticalMessage(msg) return if 'position' in attrs: self.trackingPathGroup.setPoints(self.currentFrameNo) if 'arrow' in attrs: for i, arrow_item in enumerate(self.item_dict['arrow']): begin = self.df['position'].loc[self.currentFrameNo, i].values end = self.df['arrow'].loc[self.currentFrameNo, i].values arrow_item.setPosition(begin, end) if 'path' in attrs: for path_item, path_data in zip(self.item_dict['path'], self.data_dict['path'][self.currentFrameNo]): poly = QPolygonF() for p in path_data: poly.append(QPointF(*p)) painter_path = QPainterPath() painter_path.addPolygon(poly) path_item.setPath(painter_path) pen = QPen(Qt.blue) pen.setWidth(2) path_item.setPen(pen) if 'polygon' in attrs: for path_item, path_data in zip(self.item_dict['polygon'], self.data_dict['polygon'][self.currentFrameNo]): poly = QPolygonF() for p in path_data: poly.append(QPointF(*p)) painter_path = QPainterPath() painter_path.addPolygon(poly) path_item.setPath(painter_path) pen = QPen(Qt.black) pen.setWidth(1) path_item.setPen(pen) if 'rect' in attrs: for rect_item, rect in zip(self.item_dict['rect'], self.data_dict['rect'][self.currentFrameNo]): rect_item.setRect(QRectF(QPointF(*rect[0]), QPointF(*rect[1])))
def boundingRect(self): """ Returns the shape bounding rect. :rtype: QRectF """ path = QPainterPath() path.addPath(self.selection) path.addPolygon(self.head) for shape in self.handles: path.addEllipse(shape) for shape in self.anchors.values(): path.addEllipse(shape) return path.controlPointRect()
def renderImage(self, remove_useless_background=False): if not self.Image: return paintedImage = QImage(self.Image.size(), QImage.Format_ARGB32) paintedImage.fill(Qt.transparent) painter = QPainter(paintedImage) if self.cropPolygon: painterPath = QPainterPath() painterPath.addPolygon(self.cropPolygon) painter.setClipPath(painterPath) painter.drawImage(QPoint(), self.Image) painter.end() if remove_useless_background: return paintedImage.copy(painterPath.boundingRect().toRect()) else: return paintedImage
def shape(self): """ Returns the shape of this item as a QPainterPath in local coordinates. :rtype: QPainterPath """ path = QPainterPath() path.addPath(self.selection) path.addPolygon(self.head) if self.isSelected(): for shape in self.handles: path.addEllipse(shape) for shape in self.anchors.values(): path.addEllipse(shape) return path
def uiBatteryIconPaintEvent(evt, rectSize=24): """Draw the little coloured square on the focus peaking button.""" if self._batteryPresent and (self._batteryCharging or not self._batteryBlink): powerDownLevel = api.apiValues.get('powerOffWhenMainsLost') * self.uiPowerDownThreshold warningLevel = powerDownLevel + 0.15 x,y,w,h = ( 1, 1, self.uiBatteryIcon.width() - 2, self.uiBatteryIcon.height() - 1, ) p = QPainter(self.uiBatteryIcon) #Cut out the battery outline, so the battery fill level doesn't show by #outside the "nub". Nextly, this was taken care of by an opaque box #outside the battery nub in the SVG image, but this didn't work so well #when the button was pressed or when themes were changed. We can't fill #a polygon a percentage of the way very easily, and we can't just go in #and muck with the SVG to achieve this either like we would in browser. batteryOutline = QPainterPath() batteryOutline.addPolygon(QPolygonF([ QPoint(x+3,y), QPoint(x+3,y+2), #Left battery nub chunk. QPoint(x,y+2), QPoint(x,y+h), #Bottom QPoint(x+w,y+h), QPoint(x+w,y+2), QPoint(x+w-3,y+2), #Right battery nub chunk. QPoint(x+w-3,y), ])) batteryOutline.closeSubpath() #Top of battery nub. p.setClipPath(batteryOutline, Qt.IntersectClip) p.setPen(QPen(QColor('transparent'))) if self._batteryCharge > warningLevel or self._batteryCharging: p.setBrush(QBrush(QColor('#00b800'))) else: p.setBrush(QBrush(QColor('#f20000'))) p.drawRect( x, y + h * (1-self._batteryCharge), w, h * self._batteryCharge ) type(self.uiBatteryIcon).paintEvent(self.uiBatteryIcon, evt) #Invoke the superclass to paint the battery overlay image on our new rect.
def arrow(x0, x1, arrow_size=0.3, arrow_angle=pi/5): dx, dy = x1 - x0 if dy**2 + dx**2 < arrow_size**2: return None path = QPainterPath() path.moveTo(*x0) path.lineTo(*x1) angle = atan2(dy, dx) p1 = x1 + [cos(angle + pi + arrow_angle) * arrow_size, sin(angle + pi + arrow_angle) * arrow_size] p2 = x1 + [cos(angle + pi - arrow_angle) * arrow_size, sin(angle + pi - arrow_angle) * arrow_size] path.addPolygon(QPolygonF([ QPointF(*x1), QPointF(*p1), QPointF(*p2), QPointF(*x1), ])) return path
def _createPreXoverPainterPath( elements: List[List[QPointF]], end_poly: QPolygonF = None, is_fwd: bool = True) -> QPainterPath: path = QPainterPath() next_pt = None for element in elements: start_pt = element[0] path.moveTo(start_pt) for next_pt in element[1:]: path.lineTo(next_pt) if end_poly is not None: h = end_poly.boundingRect().height()/2 xoffset = -h if is_fwd else h w = end_poly.boundingRect().width() yoffset = w if is_fwd else -w angle = -90 if is_fwd else 90 T = QTransform() T.translate(next_pt.x()+xoffset, next_pt.y()+yoffset) T.rotate(angle) path.addPolygon(T.map(end_poly)) return path
def shape(self): """ Return real shape of the item to detect collision or hover accurately :return: QPainterPath """ # detection mouse hover on arc path path = QPainterPath() path.addPolygon(QPolygonF([self.line().p1(), self.line().p2()])) # add handles at the start and end of arc path.addRect(QRectF( self.line().p1().x() - 5, self.line().p1().y() - 5, self.line().p1().x() + 5, self.line().p1().y() + 5 )) path.addRect(QRectF( self.line().p2().x() - 5, self.line().p2().y() - 5, self.line().p2().x() + 5, self.line().p2().y() + 5 )) return path
def paint(self, painter, option, widget=None): self.updatePosition() myPen = self.pen() myPen.setColor(self.myColor) painter.setPen(myPen) # painter.setBrush(self.myColor) try: angle = np.arccos(self.line().dx() / self.line().length()) except ZeroDivisionError: angle = 0.0 if self.line().dy() >= 0: angle = (np.pi * 2) - angle; l = self.line().length()*0.1 arrowP0 = self.line().p1() - QPointF(self.line().dx()/l, self.line().dy()/l) arrowP1 = self.line().p1() + QPointF(np.sin(angle + np.pi / 6) * self.arrowSize, np.cos(angle + np.pi / 6) * self.arrowSize) arrowP2 = self.line().p1() + QPointF(np.sin(angle + np.pi - np.pi / 6) * self.arrowSize, np.cos(angle + np.pi - np.pi / 6) * self.arrowSize) self.arrowHead.clear(); self.arrowHead.append(arrowP0) self.arrowHead.append(arrowP1) self.arrowHead.append(arrowP2) # painter.drawConvexPolygon(self.arrowHead) arrow = QPainterPath() arrow.addPolygon(self.arrowHead) painter.fillPath(arrow, QBrush(self.myColor)) painter.drawLine(self.line()) self.shape()
""" from PyQt5.QtCore import QRectF, QPointF from PyQt5.QtGui import QPainterPath, QPolygonF from cadnano.gui.views.pathview import pathstyles as styles from cadnano.gui.palette import getPenObj from .abstractpathtool import AbstractPathTool _BW = styles.PATH_BASE_WIDTH _PEN = getPenObj(styles.RED_STROKE, 1) _RECT = QRectF(0, 0, _BW, _BW) _PATH_ARROW_LEFT = QPainterPath() _L3_POLY = QPolygonF() _L3_POLY.append(QPointF(_BW, 0)) _L3_POLY.append(QPointF(0.25 * _BW, 0.5 * _BW)) _L3_POLY.append(QPointF(_BW, _BW)) _PATH_ARROW_LEFT.addPolygon(_L3_POLY) _PATH_ARROW_RIGHT = QPainterPath() _R3_POLY = QPolygonF() # right-hand 3' arr _R3_POLY.append(QPointF(0, 0)) _R3_POLY.append(QPointF(0.75 * _BW, 0.5 * _BW)) _R3_POLY.append(QPointF(0, _BW)) _PATH_ARROW_RIGHT.addPolygon(_R3_POLY) class BreakTool(AbstractPathTool): """ docstring for BreakTool """ def __init__(self, manager): """Summary
class InclusionEdge(AbstractEdge): """ This class implements the Inclusion edge. """ item = Item.InclusionEdge def __init__(self, complete=False, **kwargs): """ Initialize the edge. :type complete: bool """ super().__init__(**kwargs) self.complete = complete self.tail = QPolygonF() #################################################################################################################### # # # INTERFACE # # # #################################################################################################################### def copy(self, scene): """ Create a copy of the current edge. :type scene: DiagramScene """ kwargs = { 'id': self.id, 'source': self.source, 'target': self.target, 'breakpoints': self.breakpoints[:], 'complete': self.complete, } return scene.factory.create(item=self.item, scene=scene, **kwargs) @staticmethod def createHead(pos1, angle, size): """ Create the head polygon. :type pos1: QPointF :type angle: float :type size: int :rtype: QPolygonF """ rad = radians(angle) pos2 = pos1 - QPointF(sin(rad + M_PI / 3.0) * size, cos(rad + M_PI / 3.0) * size) pos3 = pos1 - QPointF(sin(rad + M_PI - M_PI / 3.0) * size, cos(rad + M_PI - M_PI / 3.0) * size) return QPolygonF([pos1, pos2, pos3]) @staticmethod def createTail(pos1, angle, size): """ Create the tail polygon. :type pos1: QPointF :type angle: float :type size: int :rtype: QPolygonF """ rad = radians(angle) pos2 = pos1 + QPointF(sin(rad + M_PI / 3.0) * size, cos(rad + M_PI / 3.0) * size) pos3 = pos1 + QPointF(sin(rad + M_PI - M_PI / 3.0) * size, cos(rad + M_PI - M_PI / 3.0) * size) return QPolygonF([pos1, pos2, pos3]) #################################################################################################################### # # # GEOMETRY # # # #################################################################################################################### def boundingRect(self): """ Returns the shape bounding rect. :rtype: QRectF """ path = QPainterPath() path.addPath(self.selection) path.addPolygon(self.head) path.addPolygon(self.tail) for shape in self.handles: path.addEllipse(shape) for shape in self.anchors.values(): path.addEllipse(shape) return path.controlPointRect() def painterPath(self): """ Returns the current shape as QPainterPath (used for collision detection). :rtype: QPainterPath """ path = QPainterPath() path.addPath(self.path) path.addPolygon(self.head) path.addPolygon(self.tail) return path def shape(self): """ Returns the shape of this item as a QPainterPath in local coordinates. :rtype: QPainterPath """ path = QPainterPath() path.addPath(self.selection) path.addPolygon(self.head) path.addPolygon(self.tail) if self.isSelected(): for shape in self.handles: path.addEllipse(shape) for shape in self.anchors.values(): path.addEllipse(shape) return path #################################################################################################################### # # # GEOMETRY UPDATE # # # #################################################################################################################### def updateEdge(self, target=None): """ Update the edge painter path and the selection polygon. :type target: QPointF """ boxSize = self.selectionSize headSize = self.headSize sourceNode = self.source targetNode = self.target sourcePos = sourceNode.anchor(self) targetPos = target or targetNode.anchor(self) self.prepareGeometryChange() self.updateAnchors() self.updateBreakPoints() self.updateZValue() createSelectionArea = self.createSelectionArea createHead = self.createHead createTail = self.createTail ################################################################################################################ # # # UPDATE EDGE PATH, SELECTION BOX, HEAD AND TAIL # # # ################################################################################################################ collection = self.computePath(sourceNode, targetNode, [sourcePos] + self.breakpoints + [targetPos]) self.path = QPainterPath() self.selection = QPainterPath() self.head = QPolygonF() self.tail = QPolygonF() if len(collection) == 1: subpath = collection[0] p1 = sourceNode.intersection(subpath) p2 = targetNode.intersection(subpath) if targetNode else subpath.p2() if p1 is not None and p2 is not None: self.path.moveTo(p1) self.path.lineTo(p2) self.selection.addPolygon(createSelectionArea(p1, p2, subpath.angle(), boxSize)) self.head = createHead(p2, subpath.angle(), headSize) if self.complete: self.tail = createTail(p1, subpath.angle(), headSize) elif len(collection) > 1: subpath1 = collection[0] subpathN = collection[-1] p11 = sourceNode.intersection(subpath1) p22 = targetNode.intersection(subpathN) if p11 and p22: p12 = subpath1.p2() p21 = subpathN.p1() self.path.moveTo(p11) self.path.lineTo(p12) self.selection.addPolygon(createSelectionArea(p11, p12, subpath1.angle(), boxSize)) for subpath in collection[1:-1]: p1 = subpath.p1() p2 = subpath.p2() self.path.moveTo(p1) self.path.lineTo(p2) self.selection.addPolygon(createSelectionArea(p1, p2, subpath.angle(), boxSize)) self.path.moveTo(p21) self.path.lineTo(p22) self.selection.addPolygon(createSelectionArea(p21, p22, subpathN.angle(), boxSize)) self.head = createHead(p22, subpathN.angle(), headSize) if self.complete: self.tail = createTail(p11, subpath1.angle(), headSize) self.updateBrush(selected=self.isSelected(), visible=self.canDraw()) #################################################################################################################### # # # DRAWING # # # #################################################################################################################### @classmethod def image(cls, **kwargs): """ Returns an image suitable for the palette. :rtype: QPixmap """ # INITIALIZATION pixmap = QPixmap(kwargs['w'], kwargs['h']) pixmap.fill(Qt.transparent) painter = QPainter(pixmap) # INIT THE LINE p1 = QPointF(((kwargs['w'] - 54) / 2), kwargs['h'] / 2) p2 = QPointF(((kwargs['w'] - 54) / 2) + 54 - 2, kwargs['h'] / 2) line = QLineF(p1, p2) # CLACULATE HEAD COORDS angle = line.angle() p1 = QPointF(line.p2().x() + 2, line.p2().y()) p2 = p1 - QPointF(sin(angle + M_PI / 3.0) * 8, cos(angle + M_PI / 3.0) * 8) p3 = p1 - QPointF(sin(angle + M_PI - M_PI / 3.0) * 8, cos(angle + M_PI - M_PI / 3.0) * 8) # INITIALIZE HEAD head = QPolygonF([p1, p2, p3]) # DRAW EDGE LINE painter.setRenderHint(QPainter.Antialiasing) painter.setPen(QPen(QColor(0, 0, 0), 1.1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) painter.drawLine(line) # DRAW EDGE HEAD painter.setPen(QPen(QColor(0, 0, 0), 1.1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) painter.setBrush(QColor(0, 0, 0)) painter.drawPolygon(head) return pixmap def paint(self, painter, option, widget=None): """ Paint the edge in the diagram scene. :type painter: QPainter :type option: QStyleOptionGraphicsItem :type widget: QWidget """ # SET THE RECT THAT NEEDS TO BE REPAINTED painter.setClipRect(option.exposedRect) # SELECTION AREA painter.setRenderHint(QPainter.Antialiasing) painter.fillPath(self.selection, self.selectionBrush) # EDGE LINE painter.setPen(self.pen) painter.drawPath(self.path) # HEAD/TAIL POLYGON painter.setPen(self.headPen) painter.setBrush(self.headBrush) painter.drawPolygon(self.head) painter.drawPolygon(self.tail) # BREAKPOINTS AND ANCHOR POINTS painter.setPen(self.handlePen) painter.setBrush(self.handleBrush) for shape in self.handles: painter.drawEllipse(shape) for shape in self.anchors.values(): painter.drawEllipse(shape)
BASE_WIDTH = styles.PATH_BASE_WIDTH BASE_RECT = QRectF(0, 0, BASE_WIDTH, BASE_WIDTH) PHOS_ITEM_WIDTH = 0.25*BASE_WIDTH TRIANGLE = QPolygonF() TRIANGLE.append(QPointF(0, 0)) TRIANGLE.append(QPointF(0.75 * PHOS_ITEM_WIDTH, 0.5 * PHOS_ITEM_WIDTH)) TRIANGLE.append(QPointF(0, PHOS_ITEM_WIDTH)) TRIANGLE.append(QPointF(0, 0)) TRIANGLE.translate(0, -0.5*PHOS_ITEM_WIDTH) T180 = QTransform() T180.rotate(-180) FWDPHOS_PP, REVPHOS_PP = QPainterPath(), QPainterPath() FWDPHOS_PP.addPolygon(TRIANGLE) REVPHOS_PP.addPolygon(T180.map(TRIANGLE)) KEYINPUT_ACTIVE_FLAG = QGraphicsItem.ItemIsFocusable PROX_ALPHA = 64 class PropertyWrapperObject(QObject): """ Attributes: animations (dict): Description brush_alpha (TYPE): Description item (TYPE): Description rotation (TYPE): Description """
def paintEvent(self, event): option = QStyleOption() option.initFrom(self) contents_rect = self.style().subElementRect(QStyle.SE_FrameContents, option, self) or self.contentsRect() # the SE_FrameContents rect is Null unless the stylesheet defines decorations if self.graphStyle == self.BarStyle: graph_width = self.__dict__['graph_width'] = int(ceil(float(contents_rect.width()) / self.horizontalPixelsPerUnit)) else: graph_width = self.__dict__['graph_width'] = int(ceil(float(contents_rect.width() - 1) / self.horizontalPixelsPerUnit) + 1) max_value = self.__dict__['max_value'] = max(chain([0], *(islice(reversed(graph.data), graph_width) for graph in self.graphs if graph.enabled))) if self.graphHeight == self.AutomaticHeight or self.graphHeight < 0: graph_height = self.__dict__['graph_height'] = max(self.scaler.get_height(max_value), self.minHeight) else: graph_height = self.__dict__['graph_height'] = max(self.graphHeight, self.minHeight) if self.graphStyle == self.BarStyle: height_scaling = float(contents_rect.height()) / graph_height else: height_scaling = float(contents_rect.height() - self.lineThickness) / graph_height painter = QStylePainter(self) painter.drawPrimitive(QStyle.PE_Widget, option) painter.setClipRect(contents_rect) painter.save() painter.translate(contents_rect.x() + contents_rect.width() - 1, contents_rect.y() + contents_rect.height() - 1) painter.scale(-1, -1) painter.setRenderHint(QStylePainter.Antialiasing, self.graphStyle != self.BarStyle) for graph in (graph for graph in self.graphs if graph.enabled and graph.data): if self.boundary is not None and 0 < self.boundary < graph_height: boundary_width = min(5.0/height_scaling, self.boundary-0, graph_height-self.boundary) pen_color = QLinearGradient(0, (self.boundary - boundary_width) * height_scaling, 0, (self.boundary + boundary_width) * height_scaling) pen_color.setColorAt(0, graph.color) pen_color.setColorAt(1, graph.over_boundary_color) brush_color = QLinearGradient(0, (self.boundary - boundary_width) * height_scaling, 0, (self.boundary + boundary_width) * height_scaling) brush_color.setColorAt(0, self.color_with_alpha(graph.color, self.fillTransparency)) brush_color.setColorAt(1, self.color_with_alpha(graph.over_boundary_color, self.fillTransparency)) else: pen_color = graph.color brush_color = self.color_with_alpha(graph.color, self.fillTransparency) dataset = islice(reversed(graph.data), graph_width) if self.graphStyle == self.BarStyle: lines = [QLineF(x*self.horizontalPixelsPerUnit, 0, x*self.horizontalPixelsPerUnit, y*height_scaling) for x, y in enumerate(dataset)] painter.setPen(QPen(pen_color, self.lineThickness)) painter.drawLines(lines) else: painter.translate(0, +self.lineThickness/2 - 1) if self.smoothEnvelope and self.smoothFactor > 0: min_value = 0 max_value = graph_height * height_scaling cx_offset = self.horizontalPixelsPerUnit / 3.0 smoothness = self.smoothFactor last_values = deque(3*[next(dataset) * height_scaling], maxlen=3) # last 3 values: 0 last, 1 previous, 2 previous previous envelope = QPainterPath() envelope.moveTo(0, last_values[0]) for x, y in enumerate(dataset, 1): x = x * self.horizontalPixelsPerUnit y = y * height_scaling * (1 - smoothness) + last_values[0] * smoothness last_values.appendleft(y) c1x = x - cx_offset * 2 c2x = x - cx_offset c1y = limit((1 + smoothness) * last_values[1] - smoothness * last_values[2], min_value, max_value) # same gradient as previous previous value to previous value c2y = limit((1 - smoothness) * last_values[0] + smoothness * last_values[1], min_value, max_value) # same gradient as previous value to last value envelope.cubicTo(c1x, c1y, c2x, c2y, x, y) else: envelope = QPainterPath() envelope.addPolygon(QPolygonF([QPointF(x*self.horizontalPixelsPerUnit, y*height_scaling) for x, y in enumerate(dataset)])) if self.fillEnvelope or graph.fill_envelope: first_element = envelope.elementAt(0) last_element = envelope.elementAt(envelope.elementCount() - 1) fill_path = QPainterPath() fill_path.moveTo(last_element.x, last_element.y) fill_path.lineTo(last_element.x + 1, last_element.y) fill_path.lineTo(last_element.x + 1, -self.lineThickness) fill_path.lineTo(-self.lineThickness, -self.lineThickness) fill_path.lineTo(-self.lineThickness, first_element.y) fill_path.connectPath(envelope) painter.fillPath(fill_path, brush_color) painter.strokePath(envelope, QPen(pen_color, self.lineThickness, join=Qt.RoundJoin)) painter.translate(0, -self.lineThickness/2 + 1) if self.boundary is not None and self.boundaryColor: painter.setRenderHint(QStylePainter.Antialiasing, False) painter.setPen(QPen(self.boundaryColor, 1.0)) painter.drawLine(0, self.boundary*height_scaling, contents_rect.width(), self.boundary*height_scaling) painter.restore() # queue the 'updated' signal to be emitted after returning to the main loop QMetaObject.invokeMethod(self, 'updated', Qt.QueuedConnection)
PP_53 = QPainterPath() # Left 5', Right 3' PainterPath PP_35 = QPainterPath() # Left 5', Right 3' PainterPath # set up PP_L5 (left 5' blue square) PP_L5.addRect(0.25 * _BASE_WIDTH, 0.125 * _BASE_WIDTH, 0.75 * _BASE_WIDTH, 0.75 * _BASE_WIDTH) # set up PP_R5 (right 5' blue square) PP_R5.addRect(0, 0.125 * _BASE_WIDTH, 0.75 * _BASE_WIDTH, 0.75 * _BASE_WIDTH) # set up PP_L3 (left 3' blue triangle) L3_POLY = QPolygonF() L3_POLY.append(QPointF(_BASE_WIDTH, 0)) L3_POLY.append(QPointF(0.25 * _BASE_WIDTH, 0.5 * _BASE_WIDTH)) L3_POLY.append(QPointF(_BASE_WIDTH, _BASE_WIDTH)) L3_POLY.append(QPointF(_BASE_WIDTH, 0)) PP_L3.addPolygon(L3_POLY) # set up PP_R3 (right 3' blue triangle) R3_POLY = QPolygonF() R3_POLY.append(QPointF(0, 0)) R3_POLY.append(QPointF(0.75 * _BASE_WIDTH, 0.5 * _BASE_WIDTH)) R3_POLY.append(QPointF(0, _BASE_WIDTH)) R3_POLY.append(QPointF(0, 0)) PP_R3.addPolygon(R3_POLY) # single base left 5'->3' PP_53.addRect(0, 0.125 * _BASE_WIDTH, 0.5 * _BASE_WIDTH, 0.75 * _BASE_WIDTH) POLY_53 = QPolygonF() POLY_53.append(QPointF(0.5 * _BASE_WIDTH, 0)) POLY_53.append(QPointF(_BASE_WIDTH, 0.5 * _BASE_WIDTH)) POLY_53.append(QPointF(0.5 * _BASE_WIDTH, _BASE_WIDTH)) PP_53.addPolygon(POLY_53)
PPL5 = QPainterPath() # Left 5' PainterPath PPR5 = QPainterPath() # Right 5' PainterPath PPL3 = QPainterPath() # Left 3' PainterPath PPR3 = QPainterPath() # Right 3' PainterPath # set up PPL5 (left 5' blue square) PPL5.addRect(0.25*_BASE_WIDTH, 0.125*_BASE_WIDTH, 0.75*_BASE_WIDTH, 0.75*_BASE_WIDTH) # set up PPR5 (right 5' blue square) PPR5.addRect(0, 0.125*_BASE_WIDTH, 0.75*_BASE_WIDTH, 0.75*_BASE_WIDTH) # set up PPL3 (left 3' blue triangle) L3_POLY = QPolygonF() L3_POLY.append(QPointF(_BASE_WIDTH, 0)) L3_POLY.append(QPointF(0.25*_BASE_WIDTH, 0.5*_BASE_WIDTH)) L3_POLY.append(QPointF(_BASE_WIDTH, _BASE_WIDTH)) PPL3.addPolygon(L3_POLY) # set up PPR3 (right 3' blue triangle) R3_POLY = QPolygonF() R3_POLY.append(QPointF(0, 0)) R3_POLY.append(QPointF(0.75*_BASE_WIDTH, 0.5*_BASE_WIDTH)) R3_POLY.append(QPointF(0, _BASE_WIDTH)) PPR3.addPolygon(R3_POLY) class ForcedXoverNode3(QGraphicsRectItem): """ This is a QGraphicsRectItem to allow actions and also a QGraphicsSimpleTextItem to allow a label to be drawn Attributes: is_forward (TYPE): Description
PXI_PP_ITEM_WIDTH = IW = 2.0 # 1.5 TRIANGLE = QPolygonF() TRIANGLE.append(QPointF(0, 0)) TRIANGLE.append(QPointF(0.75*IW, 0.5*IW)) TRIANGLE.append(QPointF(0, IW)) TRIANGLE.append(QPointF(0, 0)) # TRIANGLE.translate(-0.75*IW, -0.5*IW) TRIANGLE.translate(-0.25*IW, -0.5*IW) PXI_RECT = QRectF(0, 0, IW, IW) T90, T270 = QTransform(), QTransform() T90.rotate(90) T270.rotate(270) FWDPXI_PP, REVPXI_PP = QPainterPath(), QPainterPath() FWDPXI_PP.addPolygon(T90.map(TRIANGLE)) REVPXI_PP.addPolygon(T270.map(TRIANGLE)) # FWDPXI_PP.moveTo(-0.5*IW, 0.7*IW) # FWDPXI_PP.lineTo(0., -0.2*IW) # FWDPXI_PP.lineTo(0.5*IW, 0.7*IW) # extra1 = QPainterPath() # extra1.addEllipse(-0.5*IW, 0.5*IW, IW, 0.4*IW) # extra2 = QPainterPath() # extra2.addEllipse(-0.35*IW, 0.5*IW, 0.7*IW, 0.3*IW) # FWDPXI_PP += extra1 # FWDPXI_PP -= extra2 # REVPXI_PP.moveTo(-0.5*IW, -0.7*IW) # REVPXI_PP.lineTo(0., 0.2*IW) # REVPXI_PP.lineTo(0.5*IW, -0.7*IW)
def paint(self, painter, option, index): assert isinstance(painter, QPainter) if index.data(Qt.UserRole+1): if app_constants.HIGH_QUALITY_THUMBS: painter.setRenderHint(QPainter.SmoothPixmapTransform) painter.setRenderHint(QPainter.Antialiasing) gallery = index.data(Qt.UserRole+1) title = gallery.title artist = gallery.artist title_color = app_constants.GRID_VIEW_TITLE_COLOR artist_color = app_constants.GRID_VIEW_ARTIST_COLOR label_color = app_constants.GRID_VIEW_LABEL_COLOR # Enable this to see the defining box #painter.drawRect(option.rect) # define font size if 20 > len(title) > 15: title_size = "font-size:{}px;".format(self.font_size) elif 30 > len(title) > 20: title_size = "font-size:{}px;".format(self.font_size-1) elif 40 > len(title) >= 30: title_size = "font-size:{}px;".format(self.font_size-2) elif 50 > len(title) >= 40: title_size = "font-size:{}px;".format(self.font_size-3) elif len(title) >= 50: title_size = "font-size:{}px;".format(self.font_size-4) else: title_size = "font-size:{}px;".format(self.font_size) if 30 > len(artist) > 20: artist_size = "font-size:{}px;".format(self.font_size) elif 40 > len(artist) >= 30: artist_size = "font-size:{}px;".format(self.font_size-1) elif len(artist) >= 40: artist_size = "font-size:{}px;".format(self.font_size-2) else: artist_size = "font-size:{}px;".format(self.font_size) #painter.setPen(QPen(Qt.NoPen)) #option.rect = option.rect.adjusted(11, 10, 0, 0) option.rect.setWidth(self.W) option.rect.setHeight(self.H) rec = option.rect.getRect() x = rec[0] y = rec[1] w = rec[2] h = rec[3] text_area = QTextDocument() text_area.setDefaultFont(option.font) text_area.setHtml(""" <head> <style> #area {{ display:flex; width:{6}px; height:{7}px }} #title {{ position:absolute; color: {4}; font-weight:bold; {0} }} #artist {{ position:absolute; color: {5}; top:20px; right:0; {1} }} </style> </head> <body> <div id="area"> <center> <div id="title">{2} </div> <div id="artist">{3} </div> </div> </center> </body> """.format(title_size, artist_size, title, artist, title_color, artist_color, 130+app_constants.SIZE_FACTOR, 1+app_constants.SIZE_FACTOR)) text_area.setTextWidth(w) #chapter_area = QTextDocument() #chapter_area.setDefaultFont(option.font) #chapter_area.setHtml(""" #<font color="black">{}</font> #""".format("chapter")) #chapter_area.setTextWidth(w) def center_img(width): new_x = x if width < w: diff = w - width offset = diff//2 new_x += offset return new_x def img_too_big(start_x): txt_layout = misc.text_layout("Image is too big!", w, self.title_font, self.title_font_m) clipping = QRectF(x, y+h//4, w, app_constants.GRIDBOX_LBL_H - 10) txt_layout.draw(painter, QPointF(x, y+h//4), clip=clipping) # if we can't find a cached image pix_cache = QPixmapCache.find(self.key(gallery.profile)) if isinstance(pix_cache, QPixmap): self.image = pix_cache img_x = center_img(self.image.width()) if self.image.width() > w or self.image.height() > h: img_too_big(img_x) else: if self.image.height() < self.image.width(): #to keep aspect ratio painter.drawPixmap(QPoint(img_x,y), self.image) else: painter.drawPixmap(QPoint(img_x,y), self.image) else: self.image = QPixmap(gallery.profile) img_x = center_img(self.image.width()) QPixmapCache.insert(self.key(gallery.profile), self.image) if self.image.width() > w or self.image.height() > h: img_too_big(img_x) else: if self.image.height() < self.image.width(): #to keep aspect ratio painter.drawPixmap(QPoint(img_x,y), self.image) else: painter.drawPixmap(QPoint(img_x,y), self.image) # draw ribbon type painter.save() painter.setPen(Qt.NoPen) if app_constants.DISPLAY_GALLERY_RIBBON: type_ribbon_w = type_ribbon_l = w*0.11 rib_top_1 = QPointF(x+w-type_ribbon_l-type_ribbon_w, y) rib_top_2 = QPointF(x+w-type_ribbon_l, y) rib_side_1 = QPointF(x+w, y+type_ribbon_l) rib_side_2 = QPointF(x+w, y+type_ribbon_l+type_ribbon_w) ribbon_polygon = QPolygonF([rib_top_1, rib_top_2, rib_side_1, rib_side_2]) ribbon_path = QPainterPath() ribbon_path.setFillRule(Qt.WindingFill) ribbon_path.addPolygon(ribbon_polygon) ribbon_path.closeSubpath() painter.setBrush(QBrush(QColor(self._ribbon_color(gallery.type)))) painter.drawPath(ribbon_path) # draw if favourited if gallery.fav == 1: star_ribbon_w = star_ribbon_l = w*0.08 rib_top_1 = QPointF(x+star_ribbon_l, y) rib_side_1 = QPointF(x, y+star_ribbon_l) rib_top_2 = QPointF(x+star_ribbon_l+star_ribbon_w, y) rib_side_2 = QPointF(x, y+star_ribbon_l+star_ribbon_w) rib_star_mid_1 = QPointF((rib_top_1.x()+rib_side_1.x())/2, (rib_top_1.y()+rib_side_1.y())/2) rib_star_factor = star_ribbon_l/4 rib_star_p1_1 = rib_star_mid_1 + QPointF(rib_star_factor, -rib_star_factor) rib_star_p1_2 = rib_star_p1_1 + QPointF(-rib_star_factor, -rib_star_factor) rib_star_p1_3 = rib_star_mid_1 + QPointF(-rib_star_factor, rib_star_factor) rib_star_p1_4 = rib_star_p1_3 + QPointF(-rib_star_factor, -rib_star_factor) crown_1 = QPolygonF([rib_star_p1_1, rib_star_p1_2, rib_star_mid_1, rib_star_p1_4, rib_star_p1_3]) painter.setBrush(QBrush(QColor("yellow"))) painter.drawPolygon(crown_1) ribbon_polygon = QPolygonF([rib_top_1, rib_side_1, rib_side_2, rib_top_2]) ribbon_path = QPainterPath() ribbon_path.setFillRule(Qt.WindingFill) ribbon_path.addPolygon(ribbon_polygon) ribbon_path.closeSubpath() painter.drawPath(ribbon_path) #painter.setPen(QColor("#d35400")) #painter.drawPolyline(rib_top_1, rib_star_p1_1, rib_star_p1_2, rib_star_mid_1, rib_star_p1_4, rib_star_p1_3, rib_side_1) #painter.drawLine(rib_top_1, rib_top_2) #painter.drawLine(rib_top_2, rib_side_2) #painter.drawLine(rib_side_1, rib_side_2) painter.restore() if app_constants._REFRESH_EXTERNAL_VIEWER: if app_constants.USE_EXTERNAL_VIEWER: self.external_icon = self.file_icons.get_external_file_icon() else: self.external_icon = self.file_icons.get_default_file_icon() if gallery.state == self.G_DOWNLOAD: painter.save() dl_box = QRect(x, y, w, 20) painter.setBrush(QBrush(QColor(0,0,0,123))) painter.setPen(QColor('white')) painter.drawRect(dl_box) painter.drawText(dl_box, Qt.AlignCenter, 'Downloading...') painter.restore() else: if app_constants.DISPLAY_GALLERY_TYPE: self.type_icon = self.file_icons.get_file_icon(gallery.path) if self.type_icon and not self.type_icon.isNull(): self.type_icon.paint(painter, QRect(x+2, y+app_constants.THUMB_H_SIZE-16, 16, 16)) if app_constants.USE_EXTERNAL_PROG_ICO: if self.external_icon and not self.external_icon.isNull(): self.external_icon.paint(painter, QRect(x+w-30, y+app_constants.THUMB_H_SIZE-28, 28, 28)) def draw_text_label(lbl_h): #draw the label for text painter.save() painter.translate(x, y+app_constants.THUMB_H_SIZE) box_color = QBrush(QColor(label_color))#QColor(0,0,0,123)) painter.setBrush(box_color) rect = QRect(0, 0, w, lbl_h) #x, y, width, height painter.fillRect(rect, box_color) painter.restore() return rect if option.state & QStyle.State_MouseOver or\ option.state & QStyle.State_Selected: title_layout = misc.text_layout(title, w, self.title_font, self.title_font_m) artist_layout = misc.text_layout(artist, w, self.artist_font, self.artist_font_m) t_h = title_layout.boundingRect().height() a_h = artist_layout.boundingRect().height() if app_constants.GALLERY_FONT_ELIDE: lbl_rect = draw_text_label(min(t_h+a_h+3, app_constants.GRIDBOX_LBL_H)) else: lbl_rect = draw_text_label(app_constants.GRIDBOX_LBL_H) clipping = QRectF(x, y+app_constants.THUMB_H_SIZE, w, app_constants.GRIDBOX_LBL_H - 10) painter.setPen(QColor(title_color)) title_layout.draw(painter, QPointF(x, y+app_constants.THUMB_H_SIZE), clip=clipping) painter.setPen(QColor(artist_color)) artist_layout.draw(painter, QPointF(x, y+app_constants.THUMB_H_SIZE+t_h), clip=clipping) #painter.fillRect(option.rect, QColor) else: if app_constants.GALLERY_FONT_ELIDE: lbl_rect = draw_text_label(self.text_label_h) else: lbl_rect = draw_text_label(app_constants.GRIDBOX_LBL_H) # draw text painter.save() alignment = QTextOption(Qt.AlignCenter) alignment.setUseDesignMetrics(True) title_rect = QRectF(0,0,w, self.title_font_m.height()) artist_rect = QRectF(0,self.artist_font_m.height(),w, self.artist_font_m.height()) painter.translate(x, y+app_constants.THUMB_H_SIZE) if app_constants.GALLERY_FONT_ELIDE: painter.setFont(self.title_font) painter.setPen(QColor(title_color)) painter.drawText(title_rect, self.title_font_m.elidedText(title, Qt.ElideRight, w-10), alignment) painter.setPen(QColor(artist_color)) painter.setFont(self.artist_font) alignment.setWrapMode(QTextOption.NoWrap) painter.drawText(artist_rect, self.title_font_m.elidedText(artist, Qt.ElideRight, w-10), alignment) else: text_area.setDefaultFont(QFont(self.font_name)) text_area.drawContents(painter) ##painter.resetTransform() painter.restore() if option.state & QStyle.State_Selected: painter.save() selected_rect = QRectF(x, y, w, lbl_rect.height()+app_constants.THUMB_H_SIZE) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(QColor(164,164,164,120))) painter.drawRoundedRect(selected_rect, 5, 5) #painter.fillRect(selected_rect, QColor(164,164,164,120)) painter.restore() if gallery.dead_link: painter.save() selected_rect = QRectF(x, y, w, lbl_rect.height()+app_constants.THUMB_H_SIZE) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(QColor(255,0,0,120))) p_path = QPainterPath() p_path.setFillRule(Qt.WindingFill) p_path.addRoundedRect(selected_rect, 5,5) p_path.addRect(x,y, 20, 20) p_path.addRect(x+w-20,y, 20, 20) painter.drawPath(p_path.simplified()) painter.setPen(QColor("white")) txt_layout = misc.text_layout("Cannot find gallery source!", w, self.title_font, self.title_font_m) txt_layout.draw(painter, QPointF(x, y+h*0.3)) painter.restore() if app_constants.DEBUG: painter.save() painter.setBrush(QBrush(QColor("red"))) painter.setPen(QColor("white")) txt_l = self.title_font_m.width(str(gallery.id)) painter.drawRect(x, y+40, txt_l*2, self.title_font_m.height()) painter.drawText(x+1, y+51, str(gallery.id)) painter.restore() if option.state & QStyle.State_Selected: painter.setPen(QPen(option.palette.highlightedText().color())) else: super().paint(painter, option, index)
class InstanceOfEdge(AbstractEdge): """ This class implements the InstanceOf edge. """ item = Item.InstanceOfEdge def __init__(self, **kwargs): """ Initialize the InstanceOf edge. """ super().__init__(**kwargs) self.label = Label('instanceOf', centered=True, parent=self) #################################################################################################################### # # # INTERFACE # # # #################################################################################################################### def copy(self, scene): """ Create a copy of the current edge. :type scene: DiagramScene """ kwargs = { 'id': self.id, 'source': self.source, 'target': self.target, 'breakpoints': self.breakpoints[:], } return scene.factory.create(item=self.item, scene=scene, **kwargs) @staticmethod def createHead(pos1, angle, size): """ Create the head polygon. :type pos1: QPointF :type angle: float :type size: int :rtype: QPolygonF """ rad = radians(angle) pos2 = pos1 - QPointF(sin(rad + M_PI / 3.0) * size, cos(rad + M_PI / 3.0) * size) pos3 = pos1 - QPointF(sin(rad + M_PI - M_PI / 3.0) * size, cos(rad + M_PI - M_PI / 3.0) * size) return QPolygonF([pos1, pos2, pos3]) def updateLabel(self, points): """ Update the label text position. :type points: T <= tuple | list """ self.label.updatePos(points) #################################################################################################################### # # # GEOMETRY # # # #################################################################################################################### def boundingRect(self): """ Returns the shape bounding rect. :rtype: QRectF """ path = QPainterPath() path.addPath(self.selection) path.addPolygon(self.head) for shape in self.handles: path.addEllipse(shape) for shape in self.anchors.values(): path.addEllipse(shape) return path.controlPointRect() def painterPath(self): """ Returns the current shape as QPainterPath (used for collision detection). :rtype: QPainterPath """ path = QPainterPath() path.addPath(self.path) path.addPolygon(self.head) return path def shape(self): """ Returns the shape of this item as a QPainterPath in local coordinates. :rtype: QPainterPath """ path = QPainterPath() path.addPath(self.selection) path.addPolygon(self.head) if self.isSelected(): for shape in self.handles: path.addEllipse(shape) for shape in self.anchors.values(): path.addEllipse(shape) return path #################################################################################################################### # # # GEOMETRY UPDATE # # # #################################################################################################################### def updateEdge(self, target=None): """ Update the edge painter path and the selection polygon. :type target: QPointF """ boxSize = self.selectionSize headSize = self.headSize sourceNode = self.source targetNode = self.target sourcePos = sourceNode.anchor(self) targetPos = target or targetNode.anchor(self) self.prepareGeometryChange() self.updateAnchors() self.updateBreakPoints() self.updateZValue() createSelectionArea = self.createSelectionArea createHead = self.createHead ################################################################################################################ # # # UPDATE EDGE PATH, SELECTION BOX AND HEAD # # # ################################################################################################################ # get the list of visible subpaths for this edge collection = self.computePath(sourceNode, targetNode, [sourcePos] + self.breakpoints + [targetPos]) self.path = QPainterPath() self.selection = QPainterPath() self.head = QPolygonF() points = [] # will store all the points defining the edge not to recompute the path to update the label append = points.append # keep this shortcut and the one below since it saves a lot of computation extend = points.extend # more: http://blog.cdleary.com/2010/04/efficiency-of-list-comprehensions/ if len(collection) == 1: subpath = collection[0] p1 = sourceNode.intersection(subpath) p2 = targetNode.intersection(subpath) if targetNode else subpath.p2() if p1 is not None and p2 is not None: self.path.moveTo(p1) self.path.lineTo(p2) self.selection.addPolygon(createSelectionArea(p1, p2, subpath.angle(), boxSize)) self.head = createHead(p2, subpath.angle(), headSize) extend((p1, p2)) elif len(collection) > 1: subpath1 = collection[0] subpathN = collection[-1] p11 = sourceNode.intersection(subpath1) p22 = targetNode.intersection(subpathN) if p11 and p22: p12 = subpath1.p2() p21 = subpathN.p1() self.path.moveTo(p11) self.path.lineTo(p12) self.selection.addPolygon(createSelectionArea(p11, p12, subpath1.angle(), boxSize)) extend((p11, p12)) for subpath in collection[1:-1]: p1 = subpath.p1() p2 = subpath.p2() self.path.moveTo(p1) self.path.lineTo(p2) self.selection.addPolygon(createSelectionArea(p1, p2, subpath.angle(), boxSize)) append(p2) self.path.moveTo(p21) self.path.lineTo(p22) self.selection.addPolygon(createSelectionArea(p21, p22, subpathN.angle(), boxSize)) append(p22) self.head = createHead(p22, subpathN.angle(), headSize) self.updateLabel(points) self.updateBrush(selected=self.isSelected(), visible=self.canDraw()) #################################################################################################################### # # # DRAWING # # # #################################################################################################################### @classmethod def image(cls, **kwargs): """ Returns an image suitable for the palette. :rtype: QPixmap """ # INITIALIZATION pixmap = QPixmap(kwargs['w'], kwargs['h']) pixmap.fill(Qt.transparent) painter = QPainter(pixmap) # INITIALIZE EDGE LINE pp1 = QPointF(((kwargs['w'] - 52) / 2), kwargs['h'] / 2) pp2 = QPointF(((kwargs['w'] - 52) / 2) + 52 - 2, kwargs['h'] / 2) line = QLineF(pp1, pp2) # CALCULATE HEAD COORDINATES angle = radians(line.angle()) p1 = QPointF(line.p2().x() + 2, line.p2().y()) p2 = p1 - QPointF(sin(angle + M_PI / 3.0) * 8, cos(angle + M_PI / 3.0) * 8) p3 = p1 - QPointF(sin(angle + M_PI - M_PI / 3.0) * 8, cos(angle + M_PI - M_PI / 3.0) * 8) # INITIALIZE EDGE HEAD head = QPolygonF([p1, p2, p3]) # DRAW THE POLYGON painter.setRenderHint(QPainter.Antialiasing) painter.setPen(QPen(QColor(0, 0, 0), 1.1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) painter.drawLine(line) # DRAW HEAD painter.setPen(QPen(QColor(0, 0, 0), 1.1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) painter.setBrush(QColor(0, 0, 0)) painter.drawPolygon(head) # DRAW THE TEXT ON TOP OF THE EDGE space = 2 if Platform.identify() is Platform.Darwin else 0 painter.setFont(Font('Arial', 9, Font.Light)) painter.drawText(pp1.x() + space, (kwargs['h'] / 2) - 4, 'instanceOf') return pixmap def paint(self, painter, option, widget=None): """ Paint the edge in the diagram scene. :type painter: QPainter :type option: QStyleOptionGraphicsItem :type widget: QWidget """ # SET THE RECT THAT NEEDS TO BE REPAINTED painter.setClipRect(option.exposedRect) # SELECTION AREA painter.setRenderHint(QPainter.Antialiasing) painter.fillPath(self.selection, self.selectionBrush) # EDGE LINE painter.setPen(self.pen) painter.drawPath(self.path) # HEAD POLYGON painter.setPen(self.headPen) painter.setBrush(self.headBrush) painter.drawPolygon(self.head) # BREAKPOINTS AND ANCHOR POINTS painter.setPen(self.handlePen) painter.setBrush(self.handleBrush) for shape in self.handles: painter.drawEllipse(shape) for shape in self.anchors.values(): painter.drawEllipse(shape)