def eventFilter(self, obj, event, *args, **kwargs): """ This will assuming that sticky drag has been turned on. Attributes: _updating (bool): essentially keeps track of the event loop. To ensure that recursion does not happen as this event filter is installed on 3 widgets. This makes sure that a click only happens once. """ # preflight if not hasattr(obj, '_invisible_widget_data'): return False # interface hide_widget = obj._invisible_widget_data['hide_widget'] parent_widget = obj._invisible_widget_data['parent'] activation_widget = obj._invisible_widget_data['activation_widget'] if event.type() == QEvent.MouseButtonPress: # preflight # ensure this is only run once per click if self._updating is True: return False # ensure that the user clicked on the right widget if obj != activation_widget and hide_widget._hide_widget_filter_INVISIBLE is False: return False # toggle display flag hide_widget._hide_widget_filter_INVISIBLE = not hide_widget._hide_widget_filter_INVISIBLE # todo something here? # print("toggly joe? %s"%obj) # hide if hide_widget._hide_widget_filter_INVISIBLE is True: if self._updating is False: if obj == activation_widget: self._updating = True region = QRegion(parent_widget.frameGeometry()) hide_widget.setMask(region) # show else: if self._updating is False: self._updating = True width = hide_widget.width() height = hide_widget.height() region = QRegion(0, 0, width, height) hide_widget.setMask(QRegion()) if event.type() == QEvent.MouseButtonRelease: self._updating = False return QWidget.eventFilter(self, obj, event, *args, **kwargs)
def fillPixmap(self, widget, pixmap, offset=None): """ Fill a pixmap with the content of a widget In Qt >= 5.0 `QPixmap.fill()` is a nop, in Qt 4.x it is buggy for backgrounds with gradients. Thus `fillPixmap()` offers an alternative implementation. :param QWidget widget: Widget :param QPixmap pixmap: Pixmap to be filled :param QPoint offset: Offset .. seealso:: :py:meth:`QPixmap.fill()` """ if offset is None: offset = QPoint() rect = QRect(offset, pixmap.size()) painter = QPainter(pixmap) painter.translate(-offset) autoFillBrush = widget.palette().brush(widget.backgroundRole()) if not (widget.autoFillBackground() and autoFillBrush.isOpaque()): bg = widget.palette().brush(QPalette.Window) qwtFillRect(widget, painter, rect, bg) if widget.autoFillBackground(): qwtFillRect(widget, painter, rect, autoFillBrush) if widget.testAttribute(Qt.WA_StyledBackground): painter.setClipRegion(QRegion(rect)) opt = QStyleOption() opt.initFrom(widget) widget.style().drawPrimitive(QStyle.PE_Widget, opt, painter, widget)
def __init__(self): self.attributes = 0 self.hasClipping = False self.seriesItem = None # QwtPlotSeriesItem self.clipRegion = QRegion() self.painter = QPainter() self.from_ = None self.to = None
def grab_no_background(self) -> QPixmap: """Grab function without background.""" image = QImage(self.size(), QImage.Format_ARGB32_Premultiplied) image.fill(Qt.transparent) self.switch_grab() self.painter.begin(image) self.render(self.painter, QPoint(), QRegion(), QWidget.DrawChildren) self.switch_grab() return QPixmap.fromImage(image)
def render(self): rect = QRect(QPoint(), self.geometry().size()) self.m_backingStore.resize(rect.size()) self.m_backingStore.beginPaint(QRegion(rect)) device = self.m_backingStore.paintDevice() p = QPainter(device) p.drawImage(0, 0, self.m_image) font = QFont() font.setPixelSize(32) p.setFont(font) p.drawText(rect, 0, self.m_text) self.m_backingStore.endPaint() self.m_backingStore.flush(QRegion(rect))
def update_canvas(self): """ """ w, h = self.parent.size().width(), self.parent.size().height() self.path_full = QPainterPath() self.path_subtract = QPainterPath() self.path_decoration = QPainterPath() self.region_mask = QRegion(0, 0, w, h) self.path_full.addRect(0, 0, w, h) # Add the path if self.widgets is not None: for widget in self.widgets: temp_path = QPainterPath() # if widget is not found... find more general way to handle if widget is not None: widget.raise_() widget.show() geo = widget.frameGeometry() width, height = geo.width(), geo.height() point = widget.mapTo(self.parent, QPoint(0, 0)) x, y = point.x(), point.y() temp_path.addRect(QRectF(x, y, width, height)) temp_region = QRegion(x, y, width, height) if self.interaction_on: self.region_mask = self.region_mask.subtracted(temp_region) self.path_subtract = self.path_subtract.united(temp_path) self.path_current = self.path_full.subtracted(self.path_subtract) else: self.path_current = self.path_full if self.decoration is not None: for widget in self.decoration: temp_path = QPainterPath() widget.raise_() widget.show() geo = widget.frameGeometry() width, height = geo.width(), geo.height() point = widget.mapTo(self.parent, QPoint(0, 0)) x, y = point.x(), point.y() temp_path.addRect(QRectF(x, y, width, height)) temp_region_1 = QRegion(x - 1, y - 1, width + 2, height + 2) temp_region_2 = QRegion(x + 1, y + 1, width - 2, height - 2) temp_region = temp_region_1.subtracted(temp_region_2) if self.interaction_on: self.region_mask = self.region_mask.united(temp_region) self.path_decoration = self.path_decoration.united(temp_path) else: self.path_decoration.addRect(0, 0, 0, 0) # Add a decoration stroke around widget self.setMask(self.region_mask) self.update() self.repaint()
def drawSeries(self, seriesItem, from_, to): """ Draw a set of points of a seriesItem. When observing a measurement while it is running, new points have to be added to an existing seriesItem. drawSeries() can be used to display them avoiding a complete redraw of the canvas. Setting `plot().canvas().setAttribute(Qt.WA_PaintOutsidePaintEvent, True)` will result in faster painting, if the paint engine of the canvas widget supports this feature. :param qwt.plot_series.QwtPlotSeriesItem seriesItem: Item to be painted :param int from_: Index of the first point to be painted :param int to: Index of the last point to be painted. If to < 0 the series will be painted to its last point. """ if seriesItem is None or seriesItem.plot() is None: return canvas = seriesItem.plot().canvas() canvasRect = canvas.contentsRect() plotCanvas = canvas # XXX: cast to QwtPlotCanvas if plotCanvas and qwtHasBackingStore(plotCanvas): painter = QPainter(plotCanvas.backingStore( )) # XXX: cast plotCanvas.backingStore() to QPixmap if self.__data.hasClipping: painter.setClipRegion(self.__data.clipRegion) qwtRenderItem(painter, canvasRect, seriesItem, from_, to) painter.end() if self.testAttribute(self.FullRepaint): plotCanvas.repaint() return immediatePaint = True if not canvas.testAttribute(Qt.WA_WState_InPaintEvent): if QT_MAJOR_VERSION >= 5 or not canvas.testAttribute( Qt.WA_PaintOutsidePaintEvent): immediatePaint = False if immediatePaint: if not self.__data.painter.isActive(): self.reset() self.__data.painter.begin(canvas) canvas.installEventFilter(self) if self.__data.hasClipping: self.__data.painter.setClipRegion( QRegion(canvasRect) & self.__data.clipRegion) elif not self.__data.painter.hasClipping(): self.__data.painter.setClipRect(canvasRect) qwtRenderItem(self.__data.painter, canvasRect, seriesItem, from_, to) if self.__data.attributes & self.AtomicPainter: self.reset() elif self.__data.hasClipping: self.__data.painter.setClipping(False) else: self.reset() self.__data.seriesItem = seriesItem self.__data.from_ = from_ self.__data.to = to clipRegion = QRegion(canvasRect) if self.__data.hasClipping: clipRegion &= self.__data.clipRegion canvas.installEventFilter(self) canvas.repaint(clipRegion) canvas.removeEventFilter(self) self.__data.seriesItem = None
def __init__(self): self.pathlist = [] self.rectList = [] self.clipRegion = QRegion()
def visualRegionForSelection(self, _selection): """visualRegionForSelection is a pure virtual member function of QAbstractItemView""" return QRegion()
def activate(self, plot, plotRect, options=0x00): """ Recalculate the geometry of all components. :param qwt.plot.QwtPlot plot: Plot to be layout :param QRectF plotRect: Rectangle where to place the components :param options: Layout options """ self.invalidate() rect = QRectF(plotRect) self.__data.layoutData.init(plot, rect) if (not (options & self.IgnoreLegend) and plot.legend() and not plot.legend().isEmpty()): self.__data.legendRect = self.layoutLegend(options, rect) region = QRegion(rect.toRect()) rect = region.subtracted(QRegion( self.__data.legendRect.toRect())).boundingRect() if self.__data.legendPos == QwtPlot.LeftLegend: rect.setLeft(rect.left() + self.__data.spacing) elif self.__data.legendPos == QwtPlot.RightLegend: rect.setRight(rect.right() - self.__data.spacing) elif self.__data.legendPos == QwtPlot.TopLegend: rect.setTop(rect.top() + self.__data.spacing) elif self.__data.legendPos == QwtPlot.BottomLegend: rect.setBottom(rect.bottom() - self.__data.spacing) # +---+-----------+---+ # | Title | # +---+-----------+---+ # | | Axis | | # +---+-----------+---+ # | A | | A | # | x | Canvas | x | # | i | | i | # | s | | s | # +---+-----------+---+ # | | Axis | | # +---+-----------+---+ # | Footer | # +---+-----------+---+ # title, footer and axes include text labels. The height of each # label depends on its line breaks, that depend on the width # for the label. A line break in a horizontal text will reduce # the available width for vertical texts and vice versa. # expandLineBreaks finds the height/width for title, footer and axes # including all line breaks. dimTitle, dimFooter, dimAxes = self.expandLineBreaks(options, rect) if dimTitle > 0: self.__data.titleRect.setRect(rect.left(), rect.top(), rect.width(), dimTitle) rect.setTop(self.__data.titleRect.bottom() + self.__data.spacing) if (self.__data.layoutData.scale[QwtPlot.yLeft].isEnabled != self.__data.layoutData.scale[QwtPlot.yRight].isEnabled): self.__data.titleRect.setX(rect.left() + dimAxes[QwtPlot.yLeft]) self.__data.titleRect.setWidth(rect.width() - dimAxes[QwtPlot.yLeft] - dimAxes[QwtPlot.yRight]) if dimFooter > 0: self.__data.footerRect.setRect(rect.left(), rect.bottom() - dimFooter, rect.width(), dimFooter) rect.setBottom(self.__data.footerRect.top() - self.__data.spacing) if (self.__data.layoutData.scale[QwtPlot.yLeft].isEnabled != self.__data.layoutData.scale[QwtPlot.yRight].isEnabled): self.__data.footerRect.setX(rect.left() + dimAxes[QwtPlot.yLeft]) self.__data.footerRect.setWidth(rect.width() - dimAxes[QwtPlot.yLeft] - dimAxes[QwtPlot.yRight]) self.__data.canvasRect.setRect( rect.x() + dimAxes[QwtPlot.yLeft], rect.y() + dimAxes[QwtPlot.xTop], rect.width() - dimAxes[QwtPlot.yRight] - dimAxes[QwtPlot.yLeft], rect.height() - dimAxes[QwtPlot.xBottom] - dimAxes[QwtPlot.xTop], ) for axis in QwtPlot.AXES: if dimAxes[axis]: dim = dimAxes[axis] scaleRect = self.__data.scaleRect[axis] scaleRect.setRect(*self.__data.canvasRect.getRect()) if axis == QwtPlot.yLeft: scaleRect.setX(self.__data.canvasRect.left() - dim) scaleRect.setWidth(dim) elif axis == QwtPlot.yRight: scaleRect.setX(self.__data.canvasRect.right()) scaleRect.setWidth(dim) elif axis == QwtPlot.xBottom: scaleRect.setY(self.__data.canvasRect.bottom()) scaleRect.setHeight(dim) elif axis == QwtPlot.xTop: scaleRect.setY(self.__data.canvasRect.top() - dim) scaleRect.setHeight(dim) scaleRect = scaleRect.normalized() # +---+-----------+---+ # | <- Axis -> | # +-^-+-----------+-^-+ # | | | | | | # | | | | # | A | | A | # | x | Canvas | x | # | i | | i | # | s | | s | # | | | | # | | | | | | # +-V-+-----------+-V-+ # | <- Axis -> | # +---+-----------+---+ # The ticks of the axes - not the labels above - should # be aligned to the canvas. So we try to use the empty # corners to extend the axes, so that the label texts # left/right of the min/max ticks are moved into them. self.alignScales(options, self.__data.canvasRect, self.__data.scaleRect) if not self.__data.legendRect.isEmpty(): self.__data.legendRect = self.alignLegend(self.__data.canvasRect, self.__data.legendRect)
def get_pixmap(self) -> QPixmap: pixmap = QPixmap(self.size()) self.render(pixmap, QPoint(), QRegion(self.rect())) return pixmap