def group_object_pixmap(self, object_class_name): if object_class_name in self.group_obj_pixmap_cache: return self.group_obj_pixmap_cache[object_class_name] object_pixmap = self.object_pixmap(object_class_name) size = object_pixmap.size() width, height = size.width(), size.height() radius = width / 8 pen_width = width / 32 margin = width / 16 pen = QPen(QApplication.palette().shadow().color()) pen.setWidth(pen_width) path = QPainterPath() path.addRoundedRect(0, 0, width, height, radius, radius) pixmap = QPixmap(size) pixmap.fill(Qt.transparent) painter = QPainter(pixmap) painter.setRenderHint(QPainter.Antialiasing, True) painter.fillPath(path, QApplication.palette().window()) painter.setPen(pen) painter.drawRoundedRect(pixmap.rect().adjusted(pen_width, pen_width, -pen_width, -pen_width), radius, radius) painter.drawPixmap( pixmap.rect().adjusted(margin, margin, -width / 2, -height / 2), object_pixmap, object_pixmap.rect() ) painter.drawPixmap( pixmap.rect().adjusted(width / 2, margin, -margin, -height / 2), object_pixmap, object_pixmap.rect() ) painter.drawPixmap( pixmap.rect().adjusted(width / 2, height / 2, -margin, -margin), object_pixmap, object_pixmap.rect() ) painter.drawPixmap( pixmap.rect().adjusted(margin, height / 2, -width / 2, -margin), object_pixmap, object_pixmap.rect() ) painter.end() self.group_obj_pixmap_cache[object_class_name] = pixmap return pixmap
def paintEvent(self, event): """ custom paint event to draw horizontal line and handles at current y level """ super().paintEvent(event) painter = QPainter(self) #painter.beginNativePainting() #painter.setRenderHint(QPainter.Antialiasing) x1,y1,x2,y2 = self.rect().getCoords() #painter.setPen(QPen(Qt.gray, 1)) #painter.drawRect(self.rect()) painter.setPen(QPen(COLOR, 1)) painter.drawLine(QPoint(x1, y1+(y2-y1)/2), QPoint(x2, y1+(y2-y1)/2)) path = QPainterPath() path.moveTo(x1, y1) path.lineTo(x1, y1 + y2) path.lineTo(10, y1 + y2/2) path.lineTo(x1, y1) painter.fillPath(path, QBrush(COLOR)) path = QPainterPath() path.moveTo(x2+1, y1) path.lineTo(x2+1, y1 + y2) path.lineTo(x2 - 9, y1 + y2/2) path.lineTo(x2+1, y1) painter.fillPath(path, QBrush(COLOR)) #painter.endNativePainting() painter.end()
def paintEvent(self, event): painter = QPainter(self) painter.save() path = QPainterPath() painter.setFont(self.font) painter.setRenderHint(QPainter.Antialiasing) pen = QPen(QColor(0, 0, 0, 230)) pen_width = 3 pen.setWidth(pen_width) len = self.metrics.width(self.txt) w = self.width() px = (len - w) / 2 if px < 0: px = -px py = (self.height() - self.metrics.height()) / 2 + self.metrics.ascent() if py < 0: py = -py path.addText(px + 2, py + 2, self.font, self.txt) painter.strokePath(path, pen) painter.drawPath(path) painter.fillPath(path, QBrush(self.color)) painter.restore()
def paint( self, painter: QtGui.QPainter, option: QtWidgets.QStyleOptionGraphicsItem, widget: QtWidgets.QWidget = None, ): view = self.scene().views()[0] view_width = view.mapToScene(0, 0, self.width, 1).boundingRect().width() width, unit = self.getWidthAndUnit(view_width) # Current scale text = f"{width * self.units[self.unit] / self.units[unit]:.3g} {unit}" width = width * view.transform().m11() fm = QtGui.QFontMetrics(self.font, painter.device()) path = QtGui.QPainterPath() path.addText( self.width / 2.0 - fm.boundingRect(text).width() / 2.0, fm.ascent(), self.font, text, ) painter.strokePath(path, QtGui.QPen(QtCore.Qt.black, 2.0)) painter.fillPath(path, QtGui.QBrush(self.color, QtCore.Qt.SolidPattern)) # Draw the bar rect = QtCore.QRectF(self.width / 2.0 - width / 2.0, fm.height(), width, self.height) painter.setPen(QtGui.QPen(QtCore.Qt.black, 1.0)) painter.setBrush(QtGui.QBrush(self.color, QtCore.Qt.SolidPattern)) painter.drawRect(rect)
def paint( self, painter: QtGui.QPainter, option: QtWidgets.QStyleOptionGraphicsItem, widget: QtWidgets.QWidget = None, ): fm = QtGui.QFontMetrics(self.font, painter.device()) path = QtGui.QPainterPath() path.addText(0, fm.ascent(), self.font, self.text()) painter.strokePath(path, QtGui.QPen(QtCore.Qt.black, 2.0)) painter.fillPath(path, QtGui.QBrush(self.color, QtCore.Qt.SolidPattern))
def paint( self, painter: QtGui.QPainter, option: QtWidgets.QStyleOptionGraphicsItem, widget: QtWidgets.QWidget = None, ): width = painter.viewport().width() fm = QtGui.QFontMetrics(self.font, painter.device()) rect = QtCore.QRect(0, fm.height(), width, self.height) painter.drawPixmap(rect, self.pixmap) painter.setPen(QtGui.QPen(QtCore.Qt.black, 2.0)) painter.setBrush(QtGui.QBrush(QtCore.Qt.white, QtCore.Qt.NoBrush)) painter.drawRect(rect) path = QtGui.QPainterPath() # Todo: find a better pad value path.addText( width - fm.boundingRect(self.unit).width() - 10, fm.ascent(), self.font, self.unit, ) vrange = self.vmax - self.vmin if vrange <= 0.0: return for value in self.niceTextValues(7, trim=1): x = width * (value - self.vmin) / vrange text = f"{value:.6g}" path.addText( x - fm.boundingRect(text).width() / 2.0, fm.ascent(), self.font, text, ) if self.checkmarks: path.addRect( x - fm.lineWidth() / 2.0, fm.ascent() + fm.underlinePos(), fm.lineWidth() * 2.0, fm.underlinePos(), ) painter.strokePath(path, QtGui.QPen(QtCore.Qt.black, 2.0)) painter.fillPath(path, QtGui.QBrush(self.color, QtCore.Qt.SolidPattern))
def paint( self, painter: QtGui.QPainter, option: QtWidgets.QStyleOptionGraphicsItem, widget: QtWidgets.QWidget = None, ): fm = QtGui.QFontMetrics(self.font, painter.device()) y = fm.ascent() for text, color in zip(self._texts, self.colors): path = QtGui.QPainterPath() path.addText(0, y, self.font, text) painter.strokePath(path, QtGui.QPen(QtCore.Qt.black, 2.0)) painter.fillPath(path, QtGui.QBrush(color, QtCore.Qt.SolidPattern)) y += fm.height()
def paintPagesView(self): # This method paints the page layout, nothing more # It also paints the background at page breaks # The design is drawn only when the editor is in page mode. if (self.m_usePageMode): # Draw page breaks pageWidth = self.m_pageMetrics.pxPageSize().width() pageHeight = self.m_pageMetrics.pxPageSize().height() p = QPainter(self.viewport()) borderPen = QPen(self.palette().dark(), 1) curHeight = pageHeight - (self.verticalScrollBar().value() % pageHeight) # Horizontal offset if there is a scroll bar horizontalDelta = self.horizontalScrollBar().value() # Paint page views while there are remotely more visible pages while (curHeight < pageHeight + self.height()): p.setRenderHint(QPainter.Antialiasing) path = QPainterPath() # In painting page, height of the rect is (pageHeight - 10) # to give page break pageLayout = QRectF(0 - horizontalDelta, curHeight - pageHeight, pageWidth, pageHeight - 10) path.addRect(pageLayout) p.fillPath(path, Qt.white) p.setPen(borderPen) p.drawPath(path) # Go to next page curHeight += pageHeight
def getBrush(self, size, opacity, color, hardness, flow, spacing=1.0, jitter=0.0, orientation=0, pattern=None): """ initializes and returns a brush as a dictionary @param size: brush size @type size: int @param opacity: brush opacity, range 0..1 @type opacity: float @param color: @type color: QColor @param hardness: brush hardness, range 0..1 @type hardness: float @param flow: brush flow, range 0..1 @type flow: float @return: @rtype: dict """ s = float(self.baseSize) / 2 # set brush color if self.name == 'eraser': color = QColor(0, 0, 0, 0) else: op_max = 255 # 64 color = QColor(color.red(), color.green(), color.blue(), int(op_max * flow)) gradient = QRadialGradient(QPointF(s, s), s) gradient.setColorAt(0, color) gradient.setColorAt(hardness, color) if hardness < 1.0: # fade action to 0, starting from hardness to 1 if self.name == 'eraser': gradient.setColorAt(1, QColor(0, 0, 0, 255)) else: gradient.setColorAt(1, QColor(0, 0, 0, 0)) pxmp = self.basePixmap.copy() qp = QPainter(pxmp) # fill brush contour with gradient (pxmp color is (0,0,0,0) # outside of contourPath) qp.setCompositionMode(qp.CompositionMode_Source) qp.fillPath(self.contourPath, QBrush(gradient)) if self.preset is not None: ################################################ # we adjust the preset pixmap to pxmp size while keeping # its aspect ratio and we center it into pxmp ################################################ w, h = self.preset.width(), self.preset.height() # get the bounding rect of the scaled and centered preset # and the 2 complementary rects if w > h: rh = int(self.baseSize * h / w) # height of bounding rect m = int((self.baseSize - rh) / 2.0) # top and bottom margins r = QRect(0, m, self.baseSize, rh) r1 = QRect(0, 0, self.baseSize, m) r2 = QRect(0, rh + m, self.baseSize, m) else: rw = int(self.baseSize * w / h) # width of bounding rect m = int((self.baseSize - rw) / 2.0) # left and right margins r = QRect(m, 0, rw, self.baseSize) r1 = QRect(0, 0, m, self.baseSize) r2 = QRect(rw + m, 0, m, self.baseSize) # set opacity of r to that of preset qp.setCompositionMode(QPainter.CompositionMode_DestinationIn) qp.drawPixmap(r, self.preset) # paint the outside of r with transparent color pxmp1 = QPixmap(pxmp.size()) pxmp1.fill(QColor(0, 0, 0, 0)) qp.drawPixmap(r1, pxmp1) qp.drawPixmap(r2, pxmp1) qp.end() s = size / self.baseSize self.pxmp = pxmp.transformed(QTransform().scale( s, s).rotate(orientation)) # pxmp.scaled(size, size) pattern = pattern return { 'family': self, 'name': self.name, 'pixmap': self.pxmp, 'size': size, 'color': color, 'opacity': opacity, 'hardness': hardness, 'flow': flow, 'spacing': spacing, 'jitter': jitter, 'orientation': orientation, 'pattern': pattern, 'cursor': self.baseCursor }
def paint(self, painter: QPainter, option, widget): """ Paints the contents of the visibilitybehavior. Override the parent paint function. Only renders the visibility behavior if the configuration variable, showBehaviors, is true. :param painter: Use a Qpainter object. :type painter: QPainter :param option: It provides style options for the item. :type option: QStyleOptionGraphicsItem :param widget: QWidget :type widget: It points to the widget that is being painted on; or make it = None. :return: None :rtype: NoneType """ # Only draw visibility behaviors if "Show Visibility Behaviors" action is checked in the View drop down. if sm.StateMachine.instance.configVars.showBehaviors: arrowColor = QColor(255, 200, 50) pen = QPen(arrowColor) if self.isSelected(): pen.setStyle(Qt.DashDotLine) arrowColor = QColor(255, 0, 0) else: pen.setStyle(Qt.SolidLine) arrowColor = QColor(255, 200, 50) pen.setWidth(10) painter.setPen(pen) srcBR = self.scene().getGraphics( self._dataVB.getSrcComponent()).boundingRect(withMargins=False) dstBR = self.scene().getGraphics( self._dataVB.getDestComponent()).boundingRect( withMargins=False) lengthSrcNodeSrcEdgeList = len( self._dataVB.getSrcComponent().getSrcVisibilityBehaviors()) lengthDesNodeDesEdgeList = len( self._dataVB.getDestComponent().getDestVisibilityBehaviors()) heightSrcNode = srcBR.height() heightDesNode = dstBR.height() widthDesNode = dstBR.width() # This is the index(+1 avoid 0 in calculation) of the edge at the SourceNode's edgeSrcList srcNodeIndex = self._dataVB.getSrcComponent( ).getSrcVisibilityBehaviors().index(self._dataVB) + 1 # This is the index of the edge at the DesNode's _edgeDesList desNodeIndex = self._dataVB.getDestComponent( ).getDestVisibilityBehaviors().index(self._dataVB) + 1 srcPos = self.scene().getGraphics( self._dataVB.getSrcComponent()).scenePos() dstPos = self.scene().getGraphics( self._dataVB.getDestComponent()).scenePos() # ComponentGraphics.MARGIN = 20 x1 = srcPos.x( ) + 20 # x does not change, stay at the left most of the node y1 = srcPos.y() + (heightSrcNode / (lengthSrcNodeSrcEdgeList + 1)) * srcNodeIndex x2 = dstPos.x() + widthDesNode + 20 y2 = dstPos.y() + (heightDesNode / (lengthDesNodeDesEdgeList + 1)) * desNodeIndex self._x1 = x1 self._x2 = x2 self._y1 = y1 self._y2 = y2 # build the path and arrowhead path, leftInTrue, pathBoundingRect = self.buildPath(x1, x2, y1, y2) arrowHead, arrowHeadBoundingRect = self.buildArrowHead( x1, x2, y1, y2, leftInTrue) brTLx = min(pathBoundingRect.topLeft().x(), arrowHeadBoundingRect.topLeft().x()) brTLy = min(pathBoundingRect.topLeft().y(), arrowHeadBoundingRect.topLeft().y()) brBLx = min(pathBoundingRect.bottomLeft().x(), arrowHeadBoundingRect.bottomLeft().x()) brBLy = max(pathBoundingRect.bottomLeft().y(), arrowHeadBoundingRect.bottomLeft().y()) brTRx = max(pathBoundingRect.topRight().x(), arrowHeadBoundingRect.topRight().x()) brHeight = brBLy - brTLy brWidth = brTRx - brTLx margin = 100 self._boundingRect = QRectF(brTLx - margin, brTLy - margin, brWidth + margin * 2, brHeight + margin * 2) # Either of these lines will fix the drawing issue #self.prepareGeometryChange() self.scene().setSceneRect(self.scene().itemsBoundingRect()) painter.drawPath(path) painter.drawPath(arrowHead) painter.fillPath(arrowHead, QBrush(arrowColor))