def paintEvent(self, event): """Qt method override to paint a custom image on the Widget.""" super(FigureCanvas, self).paintEvent(event) # Prepare the rect on which the image is going to be painted : fw = self.frameWidth() rect = QRect(0 + fw, 0 + fw, self.size().width() - 2 * fw, self.size().height() - 2 * fw) if self.fig is None or self._blink_flag: return # Check/update the qpixmap buffer : qpix2paint = None for qpix in self._qpix_buffer: if qpix.size().width() == rect.width(): qpix2paint = qpix break else: if self.fmt in ['image/png', 'image/jpeg']: qpix2paint = self._qpix_orig.scaledToWidth( rect.width(), mode=Qt.SmoothTransformation) elif self.fmt == 'image/svg+xml': qpix2paint = QPixmap(svg_to_image(self.fig, rect.size())) self._qpix_buffer.append(qpix2paint) if qpix2paint is not None: # Paint the image on the widget : qp = QPainter() qp.begin(self) qp.drawPixmap(rect, qpix2paint) qp.end()
def paintEvent(self, event): """Qt method override to paint a custom image on the Widget.""" super(FigureCanvas, self).paintEvent(event) # Prepare the rect on which the image is going to be painted. fw = self.frameWidth() rect = QRect(0 + fw, 0 + fw, self.size().width() - 2 * fw, self.size().height() - 2 * fw) if self.fig is None or self._blink_flag: return # Prepare the scaled qpixmap to paint on the widget. if (self._qpix_scaled is None or self._qpix_scaled.size().width() != rect.width()): if self.fmt in ['image/png', 'image/jpeg']: self._qpix_scaled = self._qpix_orig.scaledToWidth( rect.width(), mode=Qt.SmoothTransformation) elif self.fmt == 'image/svg+xml': self._qpix_scaled = QPixmap(svg_to_image( self.fig, rect.size())) if self._qpix_scaled is not None: # Paint the image on the widget. qp = QPainter() qp.begin(self) qp.drawPixmap(rect, self._qpix_scaled) qp.end()
def renderLegend(self, painter, rect, fillBackground): """ Render the legend into a given rectangle. :param QPainter painter: Painter :param QRectF rect: Bounding rectangle :param bool fillBackground: When true, fill rect with the widget background """ if self.__data.itemMap.isEmpty(): return if fillBackground: if self.autoFillBackground() or self.testAttribute( Qt.WA_StyledBackground): QwtPainter.drawBackground(painter, rect, self) legendLayout = self.__data.view.contentsWidget.layout() if legendLayout is None: return left, right, top, bottom = self.getContentsMargins() layoutRect = QRect() layoutRect.setLeft(math.ceil(rect.left()) + left) layoutRect.setTop(math.ceil(rect.top()) + top) layoutRect.setRight(math.ceil(rect.right()) - right) layoutRect.setBottom(math.ceil(rect.bottom()) - bottom) numCols = legendLayout.columnsForWidth(layoutRect.width()) itemRects = legendLayout.layoutItems(layoutRect, numCols) index = 0 for i in range(legendLayout.count()): item = legendLayout.itemAt(i) w = item.widget() if w is not None: painter.save() painter.setClipRect(itemRects[index], Qt.IntersectClip) self.renderItem(painter, w, itemRects[index], fillBackground) index += 1 painter.restore()
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 _paint_icon(self, iconic, painter, rect, mode, state, options): """Paint a single icon.""" painter.save() color = options['color'] char = options['char'] color_options = { QIcon.On: { QIcon.Normal: (options['color_on'], options['on']), QIcon.Disabled: (options['color_on_disabled'], options['on_disabled']), QIcon.Active: (options['color_on_active'], options['on_active']), QIcon.Selected: (options['color_on_selected'], options['on_selected']) }, QIcon.Off: { QIcon.Normal: (options['color_off'], options['off']), QIcon.Disabled: (options['color_off_disabled'], options['off_disabled']), QIcon.Active: (options['color_off_active'], options['off_active']), QIcon.Selected: (options['color_off_selected'], options['off_selected']) } } color, char = color_options[state][mode] painter.setPen(QColor(color)) # A 16 pixel-high icon yields a font size of 14, which is pixel perfect # for font-awesome. 16 * 0.875 = 14 # The reason why the glyph size is smaller than the icon size is to # account for font bearing. draw_size = 0.875 * qRound(rect.height() * options['scale_factor']) prefix = options['prefix'] # Animation setup hook animation = options.get('animation') if animation is not None: animation.setup(self, painter, rect) painter.setFont(iconic.font(prefix, draw_size)) if 'offset' in options: rect = QRect(rect) rect.translate(options['offset'][0] * rect.width(), options['offset'][1] * rect.height()) painter.setOpacity(options.get('opacity', 1.0)) painter.drawText(rect, Qt.AlignCenter | Qt.AlignVCenter, char) painter.restore()
def calc_position(self, rect: QRect): columns = sum(1 for el in self._item_list if el.widget() and el.widget().isVisible()) if columns == 0: return element_width = rect.width() // columns x = rect.x() for el in self._item_list: if el.widget() and el.widget().isHidden(): continue el.setGeometry(QRect(x, rect.y(), element_width, rect.height())) x += element_width
def draw_item(self, painter): super(CavityWidget, self).draw_item(painter) x, y, w, h = self.get_bounds() rect = QRect(x, y, w, h) fm = QFontMetrics(painter.font()) sx = rect.width() / fm.width(self.cavityText) sy = rect.height() / fm.height() painter.save() painter.translate(rect.center()) painter.scale(sx, sy) painter.translate(-rect.center()) pen = QPen(QColor(240, 240, 240)) # Text color pen.setWidth(5.0) painter.setPen(pen) painter.drawText(rect, Qt.AlignCenter, self.cavityText) painter.setPen(self._pen) painter.restore()
def setGeometry(self, rc: QtCore.QRect): "`rc` - layout's rectangle w/o margins" super().setGeometry(rc) # perform the layout min_sp = self.minimal_space() if min_sp < 1: # percent min_sp *= rc.width() free_space = self[self.count()].geometry().width() - min_sp if free_space < 0 and self.count_visible() > 1: # hide more items widget = self[self.first_visible].widget() widget.hide() self.first_visible += 1 self.widget_state_changed.emit(widget, False) elif free_space > 0 and self.count_hidden(): # show more items widget = self[self.first_visible - 1].widget() w_width = widget.width() + self.spacing() if w_width <= free_space: # enough space to show next item # setGeometry is called after show QtCore.QTimer.singleShot(0, widget.show) self.first_visible -= 1 self.widget_state_changed.emit(widget, True)
def _paint_icon(self, iconic, painter, rect, mode, state, options): """Paint a single icon""" painter.save() color, char = options['color'], options['char'] if mode == QIcon.Disabled: color = options.get('color_disabled', color) char = options.get('disabled', char) elif mode == QIcon.Active: color = options.get('color_active', color) char = options.get('active', char) elif mode == QIcon.Selected: color = options.get('color_selected', color) char = options.get('selected', char) painter.setPen(QColor(color)) # A 16 pixel-high icon yields a font size of 14, which is pixel perfect # for font-awesome. 16 * 0.875 = 14 # The reason for not using full-sized glyphs is the negative bearing of # fonts. draw_size = 0.875 * qRound(rect.height() * options['scale_factor']) prefix = options['prefix'] # Animation setup hook animation = options.get('animation') if animation is not None: animation.setup(self, painter, rect) painter.setFont(iconic.font(prefix, draw_size)) if 'offset' in options: rect = QRect(rect) rect.translate(options['offset'][0] * rect.width(), options['offset'][1] * rect.height()) painter.setOpacity(options.get('opacity', 1.0)) painter.drawText(rect, Qt.AlignCenter | Qt.AlignVCenter, char) painter.restore()
def _paint_icon(self, iconic, painter, rect, mode, state, options): """Paint a single icon.""" painter.save() color = options['color'] char = options['char'] color_options = { QIcon.On: { QIcon.Normal: (options['color_on'], options['on']), QIcon.Disabled: (options['color_on_disabled'], options['on_disabled']), QIcon.Active: (options['color_on_active'], options['on_active']), QIcon.Selected: (options['color_on_selected'], options['on_selected']) }, QIcon.Off: { QIcon.Normal: (options['color_off'], options['off']), QIcon.Disabled: (options['color_off_disabled'], options['off_disabled']), QIcon.Active: (options['color_off_active'], options['off_active']), QIcon.Selected: (options['color_off_selected'], options['off_selected']) } } color, char = color_options[state][mode] alpha = None # If color comes as a tuple, it means we need to set alpha on it. if isinstance(color, tuple): alpha = color[1] color = color[0] qcolor = QColor(color) if alpha: qcolor.setAlpha(alpha) painter.setPen(qcolor) # A 16 pixel-high icon yields a font size of 14, which is pixel perfect # for font-awesome. 16 * 0.875 = 14 # The reason why the glyph size is smaller than the icon size is to # account for font bearing. draw_size = round(0.875 * rect.height() * options['scale_factor']) prefix = options['prefix'] # Animation setup hook animation = options.get('animation') if animation is not None: animation.setup(self, painter, rect) painter.setFont(iconic.font(prefix, draw_size)) if 'offset' in options: rect = QRect(rect) rect.translate(round(options['offset'][0] * rect.width()), round(options['offset'][1] * rect.height())) if 'vflip' in options and options['vflip'] == True: x_center = rect.width() * 0.5 y_center = rect.height() * 0.5 painter.translate(x_center, y_center) transfrom = QTransform() transfrom.scale(1, -1) painter.setTransform(transfrom, True) painter.translate(-x_center, -y_center) if 'hflip' in options and options['hflip'] == True: x_center = rect.width() * 0.5 y_center = rect.height() * 0.5 painter.translate(x_center, y_center) transfrom = QTransform() transfrom.scale(-1, 1) painter.setTransform(transfrom, True) painter.translate(-x_center, -y_center) if 'rotated' in options: x_center = rect.width() * 0.5 y_center = rect.height() * 0.5 painter.translate(x_center, y_center) painter.rotate(options['rotated']) painter.translate(-x_center, -y_center) painter.setOpacity(options.get('opacity', 1.0)) painter.drawText(rect, int(Qt.AlignCenter | Qt.AlignVCenter), char) painter.restore()