def setCenter(self, lon, lat): """Move the center of the visible area to new coordinates. Update the scene rect. Args: lon(float): New longitude of the center. lat(float): New latitude of the center. """ rect = QRectF(self.sceneRect()) pos = self.posFromLonLat(lon, lat) rect.moveCenter(QPointF(pos[0], pos[1])) self.setSceneRect(rect)
def setZoom(self, zoom): '''Set a new zoom level. Args: zoom (int): The new zoom level. ''' self._zoom = zoom zoomSelector = clip(zoom, self._minZoomScale, self._maxZoomScale) meters = self._scaleView[zoomSelector] if meters >= 1000: self._text = '%d km' % (meters / 1000.0) else: self._text = '%d m' % meters self._meters = meters self._meterPerPixelsEquator = self.EarthCircumference / np.power(2.0, zoom + 8) # Evaluate the bounding box of the current text anchor = self._anchor textRect = QFontMetrics(QFont()).boundingRect(self._text) if anchor == Qt.BottomRightCorner or anchor == Qt.TopRightCorner: textRect.moveLeft(-textRect.width() - 10) textRect.moveTop(-textRect.height() + 10) else: textRect.moveTop(-textRect.height() + 14) self._textRect = QRectF(textRect) self.update()
def invTransform(self, *args): """Transform from paint to scale coordinates Scalar: scalemap.invTransform(scalar) Point (QPointF): scalemap.invTransform(xMap, yMap, pos) Rectangle (QRectF): scalemap.invTransform(xMap, yMap, rect) """ if len(args) == 1: # Scalar transform return self.invTransform_scalar(args[0]) elif isinstance(args[2], QPointF): xMap, yMap, pos = args return QPointF(xMap.invTransform(pos.x()), yMap.invTransform(pos.y())) elif isinstance(args[2], QRectF): xMap, yMap, rect = args x1 = xMap.invTransform(rect.left()) x2 = xMap.invTransform(rect.right() - 1) y1 = yMap.invTransform(rect.top()) y2 = yMap.invTransform(rect.bottom() - 1) r = QRectF(x1, y1, x2 - x1, y2 - y1) return r.normalized()
def heightForWidth(self, font, flags, text, width): """ Find the height for a given width :param QFont font: Font of the text :param int flags: Bitwise OR of the flags used like in QPainter::drawText :param str text: Text to be rendered :param float width: Width :return: Calculated height """ fm = self.fontmetrics_f(font) rect = fm.boundingRect(QRectF(0, 0, width, QWIDGETSIZE_MAX), flags, text) return rect.height()
def qwtFillBackground(*args): if len(args) == 2: painter, canvas = args rects = [] if canvas.testAttribute(Qt.WA_StyledBackground): recorder = QwtStyleSheetRecorder(canvas.size()) p = QPainter(recorder) qwtDrawStyledBackground(canvas, p) p.end() if recorder.background.brush.isOpaque(): rects = recorder.clipRects else: rects += [canvas.rect()] else: r = canvas.rect() radius = canvas.borderRadius() if radius > 0.0: sz = QSizeF(radius, radius) rects += [ QRectF(r.topLeft(), sz), QRectF(r.topRight() - QPointF(radius, 0), sz), QRectF(r.bottomRight() - QPointF(radius, radius), sz), QRectF(r.bottomLeft() - QPointF(0, radius), sz), ] qwtFillBackground(painter, canvas, rects) elif len(args) == 3: painter, widget, fillRects = args if not fillRects: return if painter.hasClipping(): clipRegion = painter.transform().map(painter.clipRegion()) else: clipRegion = widget.contentsRect() bgWidget = qwtBackgroundWidget(widget.parentWidget()) for fillRect in fillRects: rect = QRectF(fillRect).toAlignedRect() if clipRegion.intersects(rect): pm = QPixmap(rect.size()) QwtPainter.fillPixmap(bgWidget, pm, widget.mapTo(bgWidget, rect.topLeft())) painter.drawPixmap(rect, pm) else: raise TypeError("%s() takes 2 or 3 argument(s) (%s given)" % ("qwtFillBackground", len(args)))
def setCornerRects(self, path): pos = QPointF(0.0, 0.0) for i in range(path.elementCount()): el = path.elementAt(i) if el.type in (QPainterPath.MoveToElement, QPainterPath.LineToElement): pos.setX(el.x) pos.setY(el.y) elif el.type == QPainterPath.CurveToElement: r = QRectF(pos, QPointF(el.x, el.y)) self.clipRects += [r.normalized()] pos.setX(el.x) pos.setY(el.y) elif el.type == QPainterPath.CurveToDataElement: if self.clipRects: r = self.clipRects[-1] r.setCoords( min([r.left(), el.x]), min([r.top(), el.y]), max([r.right(), el.x]), max([r.bottom(), el.y]), ) self.clipRects[-1] = r.normalized()
def __init__( self, *args, **kwargs ): super( GraphNodeViewWidget, self ).__init__( *args, **kwargs ) layout = QtWidgets.QVBoxLayout( self ) self.scene = GraphNodeViewScene( parent = self ) self.scene.setBackgroundBrush( Qt.black ); self.view = GraphNodeView( self.scene, parent = self ) self.view.setSceneRect( QRectF( 0,0, 10000, 10000 ) ) layout.addWidget( self.view ) layout.setSpacing( 0 ) layout.setContentsMargins( 0 , 0 , 0 , 0 ) self.nodeToItem = {}
def _generatePicture(self, p=QPainter()): p.setPen(QPen(QColor("#aaaaaa"))) p.setBrush(QBrush(QColor(80, 80, 80, 210), Qt.SolidPattern)) p.drawRoundedRect(self._bRect, 2, 2) for n in range(0, 180, 1): v = n / 180.0 a = self.cm(v) color = QColor.fromRgbF(a[0], a[1], a[2]) p.setBrush(QBrush(color)) p.setPen(QPen(color)) p.drawRect(QRect(5, 190 - n, 20, -1)) p.setBrush(QBrush(Qt.transparent)) p.setPen(QPen(QColor("#FFFFFF"))) tickRect = QRectF(32, 6, self._bRect.width() - 32, 11) p.drawText(tickRect, self.fontFlags, "{}".format(self.v_max)) # tickRect = QRectF(32, 94, self._bRect.width() - 32, 11) # p.drawText(tickRect, self.fontFlags, "{}".format(self.v_max - (self.v_max - self.v_min) / 2.)) tickRect = QRectF(32, 184, self._bRect.width() - 32, 11) p.drawText(tickRect, self.fontFlags, "{}".format(self.v_min))
def qwtDrawEllipseSymbols(painter, points, numPoints, symbol): painter.setBrush(symbol.brush()) painter.setPen(symbol.pen()) size = symbol.size() sw = size.width() sh = size.height() sw2 = 0.5 * size.width() sh2 = 0.5 * size.height() for pos in points: x = pos.x() y = pos.y() r = QRectF(x - sw2, y - sh2, sw, sh) painter.drawEllipse(r)
def __init__(self, textPen='black', barBrush=(190, 190, 190, 160), barPen=(190, 190, 190, 240), barBrushHover=(110, 110, 110, 255), barPenHover=(90, 90, 90, 255), anchor=Qt.BottomRightCorner, anchorPos=None, parent=None): """Construct a scale bar with text on the right bottom of the map Keyword Args: textPen: QPen to use for drawing the text. Default 'black'. barBrush: QBrush to use for drawing the scale bar. Default (190, 190, 190, 160) barPen: QPen to use for drawing the scale bar border. Default (190, 190, 190, 240) barBrushHover: QBrush to use for drawing the scale bar when the mouse is over it. Default (110, 110, 110, 255). barPenHover: QPen to use for drawing the scale bar borderwhen the mouse is over it. Default (90, 90, 90, 255). parent: Parent item anchor (Qt.Corner): The *corner* used as anchor for the item, Valid values are within the Qt.Corner enum anchorPos (QPointF): The distance between the item and the *corner* Note: Almost all the argumnets accepted by the functions.makeBrush() and functions.makePen() are accepted. """ QGraphicsObject.__init__(self, parent=parent) MapItem.__init__(self) self.setZValue(100) self._textPen = makePen(textPen) self._barBrush = makeBrush(barBrush) self._barPen = makePen(barPen) self._barBrushHover = makeBrush(barBrushHover) self._barPenHover = makePen(barPenHover) self._scaleView = MapScaleItem._defaultScaleVisualization.copy() self._minZoomScale = min(self._scaleView.keys()) self._maxZoomScale = max(self._scaleView.keys()) self.setAcceptHoverEvents(True) self._hover = False if anchorPos is None: anchorPos = self._posForAnchors[anchor] self._anchorPos = QPointF(anchorPos) self._anchor = anchor self._barWidth = 0 # The width of the scale bar self._text = '' # The text to display near the scale bar self._zoom = 0 # The current zoom level self._meters = 0 # The number of meters used to evaluate the size of the scale bar and its text self._meterPerPixelsEquator = 0 # The number of meters each pixel represents at the equator self._textRect = QRectF() # The bounding rect of text
def _paintRefDropIcon(self, painter, placement): self._configureBrushAndPen(painter, Qt.white, Qt.white) r = QRectF(-14, -14, 28, 28) painter.drawRoundedRect(r, 2, 2) self._configureBrushAndPen(painter, self.Blue, self.BlueAccent) r = QRectF(-10, -10, 20, 4) painter.drawRect(r) if placement == self._activeRelativeRegion: self._configureBrushAndPen(painter, self.Blue, self.BlueAccent) else: self._configureBrushAndPen(painter, self.BlueDim, self.BlueAccentDim) r = QRectF(-10, -6, 20, 16) painter.drawRect(r) if placement == self._activeRelativeRegion: self._configureBrushAndPen(painter, self.Yellow, self.YellowAccent) else: self._configureBrushAndPen(painter, self.YellowDim, self.YellowAccentDim) accent_rect = { Placement.LEFT: QRectF(-9, -5, 9, 14), Placement.RIGHT: QRectF(0, -5, 9, 14), Placement.TOP: QRectF(-9, -5, 18, 7), Placement.BOTTOM: QRectF(-9, 2, 18, 7), Placement.TAB: QRectF(-9, -5, 18, 14), } r = accent_rect[placement] if r is not None: painter.drawRect(r) painter.setPen(QPen(self.BlueAccent, 1.0, style=Qt.DotLine)) splitter_line = { Placement.LEFT: QLine(0, -5, 0, 9), Placement.RIGHT: QLine(0, -5, 0, 9), Placement.TOP: QLine(-9, 2, 9, 2), Placement.BOTTOM: QLine(-9, 2, 9, 2), Placement.TAB: None, } l = splitter_line[placement] if l is not None: painter.drawLine(l)
def draw_icon(self, painter): painter.drawEllipse(QPointF(0.5, 0.5), 0.5, 0.5) painter.drawChord(QRectF(0.0, 0.0, 1.0, 1.0), 45 * 16, -120 * 16) painter.drawChord(QRectF(0.0, 0.0, 1.0, 1.0), 135 * 16, 120 * 16) bottom_arrow_point = QPointF(0.5, 0.8) painter.drawLine(bottom_arrow_point, QPointF(0.5, 0.7)) curve_start = QPointF(0.5, 0.7) bend_angle = 25 curve_end_l = QPointF( 0.4 * math.cos(math.radians(90 + bend_angle)) + 0.5, -0.4 * math.sin(math.radians(90 + bend_angle)) + 0.5) c1 = QPointF(0.5, 0.4) path = QPainterPath(curve_start) path.quadTo(c1, curve_end_l) painter.drawPath(path) curve_end_r = QPointF( 0.4 * math.cos(math.radians(90 - bend_angle)) + 0.5, -0.4 * math.sin(math.radians(90 - bend_angle)) + 0.5) path = QPainterPath(curve_start) path.quadTo(c1, curve_end_r) painter.drawPath(path) # Draw the arrow end-caps painter.setBrush(QBrush(QColor(0, 0, 0))) arrow = QPolygonF( [QPointF(-0.025, 0.0), QPointF(0.025, 0.0), QPointF(0.0, 0.025)]) painter.drawPolygon(arrow.translated(bottom_arrow_point)) t = QTransform() t.rotate(180.0 - 25.0) arrow_l = t.map(arrow) arrow_l = arrow_l.translated(curve_end_l) painter.drawPolygon(arrow_l) t = QTransform() t.rotate(180.0 + 25.0) arrow_r = t.map(arrow) arrow_r = arrow_r.translated(curve_end_r) painter.drawPolygon(arrow_r)
def draw_icon(self, painter): painter.drawEllipse(QPointF(0.5, 0.5), 0.5, 0.5) painter.drawChord(QRectF(0.0, 0.0, 1.0, 1.0), 90 * 16, -100 * 16) painter.drawChord(QRectF(0.0, 0.0, 1.0, 1.0), 135 * 16, 100 * 16) # Draw the arrow end-caps painter.setBrush(QBrush(QColor(0, 0, 0))) top_arrow_point = QPointF(0.35, 0.15) arrow = QPolygonF([ QPointF(-0.08, 0.0), QPointF(-0.005, 0.0), QPointF(-0.005, 0.15), QPointF(0.005, 0.15), QPointF(0.005, 0.0), QPointF(0.08, 0.0), QPointF(0.00, -0.08) ]) t = QTransform() t.rotate(-25) top_arrow_r = t.map(arrow) arrow_l = top_arrow_r.translated(top_arrow_point) painter.drawPolygon(arrow_l) bottom_left_arrow_point = QPointF(0.35, 0.89) t = QTransform() t.rotate(180.0 + 25.0) arrow_r = t.map(arrow) arrow_r = arrow_r.translated(bottom_left_arrow_point) painter.drawPolygon(arrow_r) bottom_right_arrow_point = QPointF(0.85, 0.65) t = QTransform() t.rotate(180.0 - 65.0) arrow_r = t.map(arrow) arrow_r = arrow_r.translated(bottom_right_arrow_point) painter.drawPolygon(arrow_r)
def updatePosition(self, scene): """Update the position of the circle. Args: scene(MapGraphicsScene): Scene to which the circle belongs. """ pos = scene.posFromLonLat(self._lon, self._lat) self.prepareGeometryChange() # This object is centered on the lat lon point, so shift it by half width/height rect = QRectF(pos[0] - self._height // 2, pos[1] - self._width // 2, self._width, self._height) self.setRect(rect) self.setPos(QPointF(0.0, 0.0))
def __init__( self, mechanism: Dict[str, Any], path: Sequence[Sequence[_Coord]], vpoints: List[VPoint] = None, vlinks: List[VLink] = None, parent: QWidget = None ): """Input link and path data.""" super(_DynamicCanvas, self).__init__(parent) self.mechanism = mechanism self.vpoints = vpoints or [] self.vlinks = vlinks or [] self.no_mechanism = not self.vpoints or not self.vlinks use_norm = self.no_mechanism and ( self.mechanism.get('shape_only', False) or self.mechanism.get('wavelet_mode', False)) # Target path same: Dict[int, int] = self.mechanism['same'] target_path: _TargetPath = self.mechanism['target'] for i, p in target_path.items(): for j in range(i): if j in same: i -= 1 self.target_path[i] = norm_path(p) if use_norm else p self.path.path = [] for i, p in enumerate(path): if i in self.target_path and use_norm: self.path.path.append(norm_path(efd_fitting(p))) else: self.path.path.append(p) self.__index = 0 self.__interval = 1 self.__path_count = max(len(path) for path in self.path.path) - 1 self.pos: List[_Coord] = [] # Error self.error = False self.__no_error = 0 if self.no_mechanism: return # Ranges ranges: Dict[int, _Range] = self.mechanism['placement'] self.ranges.update({f"P{i}": QRectF( QPointF(values[0] - values[2], values[1] + values[2]), QSizeF(values[2] * 2, values[2] * 2) ) for i, values in ranges.items()}) # Timer self.__timer = QTimer() self.__timer.timeout.connect(self.__change_index) self.__timer.start(18)
def drawBorder(self, painter): """ Draw the border of the plot canvas :param QPainter painter: Painter .. seealso:: :py:meth:`setBorderRadius()` """ if self.__data.borderRadius > 0: if self.frameWidth() > 0: QwtPainter.drawRoundedFrame( painter, QRectF(self.frameRect()), self.__data.borderRadius, self.__data.borderRadius, self.palette(), self.frameWidth(), self.frameStyle(), ) else: if PYQT5: from qtpy.QtWidgets import QStyleOptionFrame else: try: from PyQt4.QtGui import QStyleOptionFrameV3 as QStyleOptionFrame except ImportError: from PySide2.QtWidgets import QStyleOptionFrame opt = QStyleOptionFrame() opt.initFrom(self) frameShape = self.frameStyle() & QFrame.Shape_Mask frameShadow = self.frameStyle() & QFrame.Shadow_Mask opt.frameShape = QFrame.Shape(int(opt.frameShape) | frameShape) if frameShape in ( QFrame.Box, QFrame.HLine, QFrame.VLine, QFrame.StyledPanel, QFrame.Panel, ): opt.lineWidth = self.lineWidth() opt.midLineWidth = self.midLineWidth() else: opt.lineWidth = self.frameWidth() if frameShadow == self.Sunken: opt.state |= QStyle.State_Sunken elif frameShadow == self.Raised: opt.state |= QStyle.State_Raised self.style().drawControl(QStyle.CE_ShapedFrame, opt, painter, self)
def boundingRect(self): """ Calculate the bounding rectangle The bounding rectangle is calculated once by iterating over all points and is stored for all following requests. :return: Bounding rectangle """ xmin = self.__x.min() xmax = self.__x.max() ymin = self.__y.min() ymax = self.__y.max() return QRectF(xmin, ymin, xmax - xmin, ymax - ymin)
def drawText(self, p: QPainter, innerRect: QRectF, innerRadius: float, value: float): if not self.m_format: return f = QFont(self.font()) f.setPixelSize(10) fm = QFontMetricsF(f) maxWidth = fm.width(self.valueToText(self.m_max)) delta = innerRadius / maxWidth fontSize = f.pixelSize() * delta * 0.75 f.setPixelSize(int(fontSize)) p.setFont(f) textRect = QRectF(innerRect) p.setPen(self.palette().text().color()) p.drawText(textRect, Qt.AlignCenter, self.valueToText(value))
def getGeoRect(self): ''' get geo referenced rectangle for this object Returns: QRectF (upper left x, upper left y, width, height) ''' pos0 = self.scene().posFromLonLat(self._lon0, self._lat0) pos1 = self.scene().posFromLonLat(self._lon1, self._lat1) xsize = abs(int(pos1[0] - pos0[0])) ysize = abs(int(pos0[1] - pos1[1])) ul_x = min(pos0[0], pos1[0]) ul_y = min(pos0[1], pos1[1]) rect = QRectF(ul_x, ul_y, xsize, ysize) return rect
def drawBase(self, p: QPainter, baseRect: QRectF): if self.m_barStyle == self.BarStyle.DONUT: p.setPen(QPen(self.palette().shadow().color(), self.m_outlinePenWidth)) p.setBrush(self.palette().base()) p.drawEllipse(baseRect) elif self.m_barStyle == self.BarStyle.LINE: p.setPen(QPen(self.palette().base().color(), self.m_outlinePenWidth)) p.setBrush(Qt.NoBrush) p.drawEllipse(baseRect.adjusted(self.m_outlinePenWidth / 2, self.m_outlinePenWidth / 2, -self.m_outlinePenWidth / 2, -self.m_outlinePenWidth / 2)) elif self.m_barStyle in (self.BarStyle.PIE, self.BarStyle.EXPAND): p.setPen(QPen(self.palette().base().color(), self.m_outlinePenWidth)) p.setBrush(self.palette().base()) p.drawEllipse(baseRect)
def drawBorder(self, painter): """ Draw the border of the plot canvas :param QPainter painter: Painter .. seealso:: :py:meth:`setBorderRadius()` """ if self.__data.borderRadius > 0: if self.frameWidth() > 0: QwtPainter.drawRoundedFrame( painter, QRectF(self.frameRect()), self.__data.borderRadius, self.__data.borderRadius, self.palette(), self.frameWidth(), self.frameStyle(), ) else: opt = QStyleOptionFrame() opt.initFrom(self) try: shape_mask = QFrame.Shape_Mask.value shadow_mask = QFrame.Shadow_Mask.value except AttributeError: shape_mask = QFrame.Shape_Mask shadow_mask = QFrame.Shadow_Mask frameShape = self.frameStyle() & shape_mask frameShadow = self.frameStyle() & shadow_mask opt.frameShape = QFrame.Shape(int(opt.frameShape) | frameShape) if frameShape in ( QFrame.Box, QFrame.HLine, QFrame.VLine, QFrame.StyledPanel, QFrame.Panel, ): opt.lineWidth = self.lineWidth() opt.midLineWidth = self.midLineWidth() else: opt.lineWidth = self.frameWidth() if frameShadow == self.Sunken: opt.state |= QStyle.State_Sunken elif frameShadow == self.Raised: opt.state |= QStyle.State_Raised self.style().drawControl(QStyle.CE_ShapedFrame, opt, painter, self)
def draw_icon(self, painter): painter.drawEllipse(QPointF(0.5, 0.5), 0.5, 0.5) painter.drawChord(QRectF(0.0, 0.0, 1.0, 1.0), 45 * 16, -120 * 16) painter.drawChord(QRectF(0.0, 0.0, 1.0, 1.0), 135 * 16, 120 * 16) circle_arrow_point = QPointF(0.3, 0.5) brush = painter.brush() pen = painter.pen() painter.setBrush(self.centerBrush) painter.setPen(QColor("transparent")) painter.drawEllipse(QPointF(0.5, 0.5), 0.2, 0.2) painter.setBrush(brush) painter.setPen(pen) painter.drawArc(QRectF(0.3, 0.3, 0.4, 0.4), 90 * 16, -270 * 16) arrow = QPolygonF( [QPointF(-0.025, 0.0), QPointF(0.025, 0.0), QPointF(0.0, -0.025)]) painter.setBrush(QBrush(QColor(0, 0, 0))) painter.drawPolygon(arrow.translated(circle_arrow_point))
def controlPointRect(self): """ The control point rectangle is the bounding rectangle of all control points of the paths and the target rectangles of the images/pixmaps. :return: Control point rectangle .. seealso:: :py:meth:`boundingRect()`, :py:meth:`scaledBoundingRect()` """ if self.__data.pointRect.width() < 0: return QRectF() return self.__data.pointRect
def drawSymbol(self, painter, point_or_rect): """ Draw the symbol into a rectangle The symbol is painted centered and scaled into the target rectangle. It is always painted uncached and the pin point is ignored. This method is primarily intended for drawing a symbol to the legend. :param QPainter painter: Painter :param point_or_rect: Position or target rectangle of the symbol in screen coordinates :type point_or_rect: QPointF or QPoint or QRectF """ if isinstance(point_or_rect, (QPointF, QPoint)): # drawSymbol( QPainter *, const QPointF & ) self.drawSymbols(painter, [point_or_rect]) return # drawSymbol( QPainter *, const QRectF & ) rect = point_or_rect assert isinstance(rect, QRectF) if self.__data.style == QwtSymbol.NoSymbol: return if self.__data.style == QwtSymbol.Graphic: self.__data.graphic.graphic.render(painter, rect, Qt.KeepAspectRatio) elif self.__data.style == QwtSymbol.Path: if self.__data.path.graphic.isNull(): self.__data.path.graphic = qwtPathGraphic( self.__data.path.path, self.__data.pen, self.__data.brush) self.__data.path.graphic.render(painter, rect, Qt.KeepAspectRatio) return elif self.__data.style == QwtSymbol.SvgDocument: if self.__data.svg.renderer is not None: scaledRect = QRectF() sz = QSizeF(self.__data.svg.renderer.viewBoxF().size()) if not sz.isEmpty(): sz.scale(rect.size(), Qt.KeepAspectRatio) scaledRect.setSize(sz) scaledRect.moveCenter(rect.center()) else: scaledRect = rect self.__data.svg.renderer.render(painter, scaledRect) else: br = QRect(self.boundingRect()) ratio = min( [rect.width() / br.width(), rect.height() / br.height()]) painter.save() painter.translate(rect.center()) painter.scale(ratio, ratio) isPinPointEnabled = self.__data.isPinPointEnabled self.__data.isPinPointEnabled = False pos = QPointF() self.renderSymbols(painter, pos, 1) self.__data.isPinPointEnabled = isPinPointEnabled painter.restore()
def updatePosition(self, scene): """Update the position of the circle. Args: scene(MapGraphicsScene): Scene to which the circle belongs. """ pos0 = scene.posFromLonLat(self._lon0, self._lat0) pos1 = scene.posFromLonLat(self._lon1, self._lat1) width = abs(int(pos1[0] - pos0[0])) height = abs(int(pos0[1] - pos1[1])) self.prepareGeometryChange() rect = QRectF(pos0[0], pos0[1], width, height) self.setRect(rect) self.setPos(QPointF(0.0, 0.0))
def boundingRect(self): """ The bounding rectangle is the :py:meth:`controlPointRect` extended by the areas needed for rendering the outlines with unscaled pens. :return: Bounding rectangle of the graphic .. seealso:: :py:meth:`controlPointRect`, :py:meth:`scaledBoundingRect` """ if self.__data.boundingRect.width() < 0: return QRectF() return self.__data.boundingRect
def __init__(self, width, height): super(RGBAForegroundGradient, self).__init__() self.setFlag(QGraphicsItem.ItemIsSelectable, True) self._rectangle = QRectF(0, 0, width, height) self._brush = QBrush(Qt.black) self._gradient = draw.create1DGradient( 100, 100, direction=Qt.Vertical, color1=(0, 0, 0, 0), color2=(1, 1, 1, 1), ) self.setGradient(self._gradient)
def drawBorder(self): p = self._painter bw = float(self._border_width) br = self._border_radius p.setBrush(Qt.transparent) border_pen = QPen() border_pen.setWidth(int(bw)) border_pen.setColor(self._border_color) p.setPen(border_pen) # deal with orientation if self._orientation == Qt.Horizontal: rect = QRectF(bw / 2, bw / 2, self.width() - bw, self.height() - bw) else: # must be Qt.Vertical rect = QRectF(bw / 2, bw / 2, self.height() - bw, self.width() - bw) p.drawRoundedRect(rect, br, br)
def qwtStrokedPathRect(painter, path): stroker = QPainterPathStroker() stroker.setWidth(painter.pen().widthF()) stroker.setCapStyle(painter.pen().capStyle()) stroker.setJoinStyle(painter.pen().joinStyle()) stroker.setMiterLimit(painter.pen().miterLimit()) rect = QRectF() if qwtHasScalablePen(painter): stroke = stroker.createStroke(path) rect = painter.transform().map(stroke).boundingRect() else: mappedPath = painter.transform().map(path) mappedPath = stroker.createStroke(mappedPath) rect = mappedPath.boundingRect() return rect
def paintEvent(self, event): """ Paint events are sent to widgets that need to update themselves, for instance when part of a widget is exposed because a covering widget was moved. At PyDMSymbol this method handles the alarm painting with parameters from the stylesheet and draws the proper image. Parameters ---------- event : QPaintEvent """ self._painter.begin(self) opt = QStyleOption() opt.initFrom(self) self.style().drawPrimitive(QStyle.PE_Widget, opt, self._painter, self) # self._painter.setRenderHint(QPainter.Antialiasing) if self._current_key is None: self._painter.end() return image_to_draw = self._state_images.get(self._current_key, (None, None))[1] if image_to_draw is None: self._painter.end() return if isinstance(image_to_draw, QPixmap): w = float(image_to_draw.width()) h = float(image_to_draw.height()) if self._aspect_ratio_mode == Qt.IgnoreAspectRatio: scale = (event.rect().width() / w, event.rect().height() / h) elif self._aspect_ratio_mode == Qt.KeepAspectRatio: sf = min(event.rect().width() / w, event.rect().height() / h) scale = (sf, sf) elif self._aspect_ratio_mode == Qt.KeepAspectRatioByExpanding: sf = max(event.rect().width() / w, event.rect().height() / h) scale = (sf, sf) self._painter.scale(scale[0], scale[1]) self._painter.drawPixmap(event.rect().x(), event.rect().y(), image_to_draw) elif isinstance(image_to_draw, QSvgRenderer): draw_size = QSizeF(image_to_draw.defaultSize()) draw_size.scale(QSizeF(event.rect().size()), self._aspect_ratio_mode) image_to_draw.render( self._painter, QRectF(0.0, 0.0, draw_size.width(), draw_size.height())) self._painter.end()
def drawContents(self, painter): """ Redraw the text and focus indicator :param QPainter painter: Painter """ r = self.textRect() if r.isEmpty(): return painter.setFont(self.font()) painter.setPen(self.palette().color(QPalette.Active, QPalette.Text)) self.drawText(painter, QRectF(r)) if self.hasFocus(): m = 2 focusRect = self.contentsRect().adjusted(m, m, -m + 1, -m + 1) QwtPainter.drawFocusRect(painter, self, focusRect)
def qwtDrawRectSymbols(painter, points, numPoints, symbol): size = symbol.size() pen = QPen(symbol.pen()) pen.setJoinStyle(Qt.MiterJoin) painter.setPen(pen) painter.setBrush(symbol.brush()) painter.setRenderHint(QPainter.Antialiasing, False) sw = size.width() sh = size.height() sw2 = 0.5 * size.width() sh2 = 0.5 * size.height() for pos in points: x = pos.x() y = pos.y() r = QRectF(x - sw2, y - sh2, sw, sh) painter.drawRect(r)
def drawBackground(self): bw = float(self._border_width) br = self._border_radius w = self.sliderPositionFromValue(self.minimum, self.maximum, self._value, self._bar_length) h = self._bar_width rect = QRectF(bw / 2, bw / 2, w - bw, h - bw) p = self._painter # draw the load meter value bar p.setPen(Qt.transparent) p.setBrush(self.gradient) p.drawRoundedRect(rect, br, br)
class MapScaleItem(QGraphicsObject, MapItem): """Scale bar for the visualization of the scale of teh map. The scale bar is located on the bottom right of the map and can' be moved. The scale bar accepts hover events and change its color. """ QtParentClass = QGraphicsObject EarthCircumference = 1000.0 * 6372.7982 * 2.0 * np.pi DegToRad = np.pi / 180.0 _defaultScaleVisualization = { 21: 5, 20: 10, 19: 20, 18: 20, 17: 50, 16: 100, 15: 200, 14: 500, 13: 1 * 1000, 12: 2 * 1000, 11: 5 * 1000, 10: 10 * 1000, 9: 20 * 1000, 8: 50 * 1000, 7: 100 * 1000, 6: 200 * 1000, 5: 200 * 1000, 4: 500 * 1000, 3: 1000 * 1000, } """dict: Default meters that will be shown within the scale for each zoom value. """ _posForAnchors = { Qt.TopLeftCorner: QPointF(20.0, 15.0), Qt.TopRightCorner: QPointF(20.0, -15.0), Qt.BottomLeftCorner: QPointF(20.0, -15.0), Qt.BottomRightCorner: QPointF(20.0, 15.0), } def __init__(self, textPen='black', barBrush=(190, 190, 190, 160), barPen=(190, 190, 190, 240), barBrushHover=(110, 110, 110, 255), barPenHover=(90, 90, 90, 255), anchor=Qt.BottomRightCorner, anchorPos=None, parent=None): """Construct a scale bar with text on the right bottom of the map Keyword Args: textPen: QPen to use for drawing the text. Default 'black'. barBrush: QBrush to use for drawing the scale bar. Default (190, 190, 190, 160) barPen: QPen to use for drawing the scale bar border. Default (190, 190, 190, 240) barBrushHover: QBrush to use for drawing the scale bar when the mouse is over it. Default (110, 110, 110, 255). barPenHover: QPen to use for drawing the scale bar borderwhen the mouse is over it. Default (90, 90, 90, 255). parent: Parent item anchor (Qt.Corner): The *corner* used as anchor for the item, Valid values are within the Qt.Corner enum anchorPos (QPointF): The distance between the item and the *corner* Note: Almost all the argumnets accepted by the functions.makeBrush() and functions.makePen() are accepted. """ QGraphicsObject.__init__(self, parent=parent) MapItem.__init__(self) self.setZValue(100) self._textPen = makePen(textPen) self._barBrush = makeBrush(barBrush) self._barPen = makePen(barPen) self._barBrushHover = makeBrush(barBrushHover) self._barPenHover = makePen(barPenHover) self._scaleView = MapScaleItem._defaultScaleVisualization.copy() self._minZoomScale = min(self._scaleView.keys()) self._maxZoomScale = max(self._scaleView.keys()) self.setAcceptHoverEvents(True) self._hover = False if anchorPos is None: anchorPos = self._posForAnchors[anchor] self._anchorPos = QPointF(anchorPos) self._anchor = anchor self._barWidth = 0 # The width of the scale bar self._text = '' # The text to display near the scale bar self._zoom = 0 # The current zoom level self._meters = 0 # The number of meters used to evaluate the size of the scale bar and its text self._meterPerPixelsEquator = 0 # The number of meters each pixel represents at the equator self._textRect = QRectF() # The bounding rect of text def _sceneChanged(self, oldScene, newScene): if oldScene is not None: oldScene.sceneRectChanged.disconnect(self._setSceneRect) if newScene is not None: newScene.sceneRectChanged.connect(self._setSceneRect) # Setup the new position of the item self.setZoom(newScene.zoom()) self._setSceneRect(newScene.sceneRect()) def updatePosition(self, scene): # Nothing to do here pass def boundingRect(self): anchor = self._anchor if anchor == Qt.BottomRightCorner or anchor == Qt.TopRightCorner: return QRectF(0, 0, self._barWidth + 3, 10).united(self._textRect) else: textRect = self._textRect.translated(self._barWidth + 10, 0) return QRectF(0, 0, self._barWidth + 3, 10).united(textRect) def paint(self, painter, option, widget): if self._hover: painter.setPen(self._barPenHover) painter.setBrush(self._barBrushHover) else: painter.setPen(self._barPen) painter.setBrush(self._barBrush) painter.drawRoundedRect(0, 0, self._barWidth, 10, 3, 3) anchor = self._anchor if anchor == Qt.BottomRightCorner or anchor == Qt.TopRightCorner: textRect = self._textRect else: textRect = self._textRect.translated(self._barWidth + 10, 0) painter.setPen(self._textPen) painter.drawText(textRect, Qt.TextSingleLine, self._text) @Slot(QRectF) def _setSceneRect(self, rect): self._updateScaleBar() anchorPos = self._anchorPos anchor = self._anchor newPos = None if anchor == Qt.BottomRightCorner: newPos = rect.bottomRight() - anchorPos - QPointF(self._barWidth, 0.0) elif anchor == Qt.TopRightCorner: newPos = rect.topRight() - anchorPos - QPointF(self._barWidth, 0.0) elif anchor == Qt.TopLeftCorner: newPos = rect.topLeft() + anchorPos elif anchor == Qt.BottomLeftCorner: newPos = rect.bottomLeft() + anchorPos else: raise NotImplementedError('Other corner have not actually been implemented') self.setPos(newPos) def _updateScaleBar(self): scene = self.scene() if scene is None: self.setVisible(False) return self.setVisible(True) centerYRad = scene.center().y() * self.DegToRad meterPerPixels = self._meterPerPixelsEquator * np.cos(centerYRad) self._barWidth = int(self._meters / meterPerPixels) def setZoom(self, zoom): '''Set a new zoom level. Args: zoom (int): The new zoom level. ''' self._zoom = zoom zoomSelector = clip(zoom, self._minZoomScale, self._maxZoomScale) meters = self._scaleView[zoomSelector] if meters >= 1000: self._text = '%d km' % (meters / 1000.0) else: self._text = '%d m' % meters self._meters = meters self._meterPerPixelsEquator = self.EarthCircumference / np.power(2.0, zoom + 8) # Evaluate the bounding box of the current text anchor = self._anchor textRect = QFontMetrics(QFont()).boundingRect(self._text) if anchor == Qt.BottomRightCorner or anchor == Qt.TopRightCorner: textRect.moveLeft(-textRect.width() - 10) textRect.moveTop(-textRect.height() + 10) else: textRect.moveTop(-textRect.height() + 14) self._textRect = QRectF(textRect) self.update() def setScaleForZoom(self, zoomLevel, metersInScaleBar): """Set the scale in meters/kilometers to be shown for a zoom level Args: zoomLevel(int): Level of the zoom metersInScaleBar(int): Meters to be shown in the scale bar """ if zoomLevel > self._maxZoomScale + 1: raise ValueError('zoomLevel must be at least %d' % (self._maxZoomScale + 1)) if zoomLevel < self._minZoomScale - 1: raise ValueError('zoomLevel must be at minimum %d' % (self._minZoomScale + 1)) self._scaleView[zoomLevel] = metersInScaleBar self._minZoomScale = min(self._scaleView.keys()) self._maxZoomScale = max(self._scaleView.keys()) # Re-evaluate the scale bar for the current zoom self.setZoom(self._zoom) self.update() def restoreDefaultScaleLevels(self): """Restore the default meter scale for the zoom levels """ self._scaleView = MapScaleItem._defaultScaleVisualization.copy() self._minZoomScale = min(self._scaleView.keys()) self._maxZoomScale = max(self._scaleView.keys()) # Re-evaluate the scale bar for the current zoom self.setZoom(self._zoom) self.update() def setColors(self, **kwargs): """Set a new color for the scale bar and the text Keyword Args: textPen: QPen to use for drawing the text. Default do not change. barBrush: QBrush to use for drawing the scale bar. Default do not change. barPen: QPen to use for drawing the scale bar border.Default do not change. barBrushHover: QBrush to use for drawing the scale bar when the mouse is over it. Default do not change. barPenHover: QPen to use for drawing the scale bar borderwhen the mouse is over it. Default do not change. """ if 'textPen' in kwargs: self._textPen = makePen(kwargs['textPen']) if 'barBrush' in kwargs: self._barBrush = makeBrush(kwargs['barBrush']) if 'barPen' in kwargs: self._barPen = makePen(kwargs['barPen']) if 'barBrushHover' in kwargs: self._barBrushHover = makeBrush(kwargs['barBrushHover']) if 'barPenHover' in kwargs: self._barPenHover = makePen(kwargs['barPenHover']) self.update() def hoverEnterEvent(self, event): event.accept() self._hover = True self.update() def hoverLeaveEvent(self, event): event.accept() self._hover = False self.update()