Example #1
0
    def paintEvent(self, event):
        if self.__pixmap.isNull():
            return

        sourcerect = QRect(QPoint(0, 0), self.__pixmap.size())
        pixsize = QSizeF(self.__pixmap.size())
        rect = self.contentsRect()
        pixsize.scale(QSizeF(rect.size()), Qt.KeepAspectRatio)
        targetrect = QRectF(QPointF(0, 0), pixsize)
        targetrect.moveCenter(QPointF(rect.center()))
        painter = QPainter(self)
        painter.setRenderHint(QPainter.SmoothPixmapTransform)
        painter.drawPixmap(targetrect, self.__pixmap, QRectF(sourcerect))
        painter.end()
 def __naturalsh(self):
     fm = QFontMetrics(self.font())
     spacing = self.__spacing
     N = len(self.__items)
     width = max((fm.width(text) for text in self.__items),
                 default=0)
     height = N * fm.height() + (N - 1) * spacing
     return QSizeF(width, height)
Example #3
0
 def boundingRect(self):
     if hasattr(self, "attr"):
         attr_rect = QRectF(QPointF(0, -self.attr_text_h),
                            QSizeF(self.attr_text_w, self.attr_text_h))
     else:
         attr_rect = QRectF(0, 0, 1, 1)
     rect = self.rect().adjusted(-5, -5, 5, 5)
     return rect | attr_rect
    def __init__(self, widget, parent=None, max_size=150, **kwargs):
        self._max_size = QSizeF(max_size, max_size)
        # We store the offsets from the top left corner to move widget properly
        self.__offset_x = self.__offset_y = 0

        super().__init__(widget, parent, **kwargs)

        self._resize_widget()
Example #5
0
 def __naturalsh(self) -> QSizeF:
     """Return the natural size hint (preferred sh with no constraints)."""
     fm = QFontMetrics(self.font())
     spacing = self.__spacing
     N = len(self.__items)
     width = self.__width_for_font(self.font())
     height = N * fm.height() + max(N - 1, 0) * spacing
     return QSizeF(width, height)
Example #6
0
    def sizeHint(self, which, constraint=QSizeF()):
        if which == Qt.PreferredSize:
            sh = self.__naturalsh()
            if 0 < constraint.height() < sh.height():
                sh = scaled(sh, constraint, Qt.KeepAspectRatioByExpanding)
            return sh

        return super().sizeHint(which, constraint)
Example #7
0
    def sizeHint(self, which, constraint=QRectF()):
        # type: (Qt.SizeHint, QSizeF) -> QSizeF
        pw = 1.
        sh = QSizeF()
        if which == Qt.MinimumSize:
            sh = QSizeF(pw, pw)
        elif which == Qt.PreferredSize:
            sh = QSizeF(pw, 30.)
        elif which == Qt.MaximumSize:
            sh = QSizeF(pw, QWIDGETSIZE_MAX)

        if self.__orientation == Qt.Horizontal:
            sh = sh.transposed()
        return sh
Example #8
0
 def adjustSize(self):
     """Resize to a reasonable size.
     """
     self.__textItem.setTextWidth(-1)
     self.__textItem.adjustSize()
     size = self.__textItem.boundingRect().size()
     left, top, right, bottom = self.textMargins()
     geom = QRectF(self.pos(), size + QSizeF(left + right, top + bottom))
     self.setGeometry(geom)
Example #9
0
    def __init__(self, color, parent):
        super().__init__(parent)

        height, width = self.SIZE.height(), self.SIZE.width()
        self.__circle = QGraphicsEllipseItem(0, 0, height, width)
        self.__circle.setBrush(QBrush(color))
        self.__circle.setPen(QPen(QColor(0, 0, 0, 0)))
        self.__circle.setParentItem(self)
        self._size_hint = QSizeF(self.__circle.boundingRect().size())
    def pixmapTransform(self) -> QTransform:
        if self.__pixmap.isNull():
            return QTransform()

        pxsize = QSizeF(self.__pixmap.size())
        crect = self.contentsRect()
        transform = QTransform()
        transform = transform.translate(crect.left(), crect.top())

        if self.__scaleContents:
            csize = scaled(pxsize, crect.size(), self.__aspectMode)
        else:
            csize = pxsize

        xscale = csize.width() / pxsize.width()
        yscale = csize.height() / pxsize.height()

        return transform.scale(xscale, yscale)
Example #11
0
    def paint(self, painter, option, index):
        # type: (QPainter, QStyleOptionViewItem, QModelIndex) -> None
        scene = index.data(Qt.DisplayRole)  # type: Optional[QGraphicsScene]
        if scene is None:
            super().paint(painter, option, index)
            return

        painter.save()
        rect = QRectF(QPointF(option.rect.topLeft()),
                      QSizeF(option.rect.size()))
        if option.state & QStyle.State_Selected:
            painter.setPen(QPen(QColor(125, 162, 206, 192)))
            painter.setBrush(QBrush(QColor(217, 232, 252, 192)))
        else:
            painter.setPen(QPen(QColor('#ebebeb')))
        painter.drawRoundedRect(rect, 3, 3)
        painter.restore()

        painter.setRenderHint(QPainter.Antialiasing)

        # The sceneRect doesn't automatically shrink to fit contents, so when
        # drawing smaller tree, remove any excess space aroung the tree
        scene.setSceneRect(scene.itemsBoundingRect())

        # Make sure the tree is centered in the item cell
        # First, figure out how much we get the bounding rect to the size of
        # the available painting rect
        scene_rect = scene.itemsBoundingRect()
        w_scale = option.rect.width() / scene_rect.width()
        h_scale = option.rect.height() / scene_rect.height()
        # In order to keep the aspect ratio, we use the same scale
        scale = min(w_scale, h_scale)
        # Figure out the rescaled scene width/height
        scene_w = scale * scene_rect.width()
        scene_h = scale * scene_rect.height()
        # Figure out how much we have to offset the rect so that the scene will
        # be painted in the centre of the rect
        offset_w = (option.rect.width() - scene_w) / 2
        offset_h = (option.rect.height() - scene_h) / 2
        offset = option.rect.topLeft() + QPointF(offset_w, offset_h)
        # Finally, we have all the data for the new rect in which to render
        target_rect = QRectF(offset, QSizeF(scene_w, scene_h))

        scene.render(painter, target=target_rect, mode=Qt.KeepAspectRatio)
Example #12
0
    def sizeHint(self, which: Qt.SizeHint, constraint=QSizeF()) -> QSizeF:
        # reimplemented
        fm = QFontMetrics(self.font())
        spacing = fm.lineSpacing()
        mleft, mtop, mright, mbottom = self.getContentsMargins()

        if self._root and which == Qt.PreferredSize:
            nleaves = len(
                [node for node in self._items.keys() if not node.branches])
            base = max(10, min(spacing * 16, 250))
            if self.orientation in [self.Left, self.Right]:
                return QSizeF(base, spacing * nleaves + mleft + mright)
            else:
                return QSizeF(spacing * nleaves + mtop + mbottom, base)

        elif which == Qt.MinimumSize:
            return QSizeF(mleft + mright + 10, mtop + mbottom + 10)
        else:
            return QSizeF()
Example #13
0
    def paint(self, painter, option, widget=0):
        if self._pixmap.isNull():
            return

        rect = self.contentsRect()
        pixsize = QSizeF(self._pixmap.size())
        aspectmode = (Qt.KeepAspectRatio if self._keepAspect
                      else Qt.IgnoreAspectRatio)
        pixsize.scale(rect.size(), aspectmode)
        pixrect = QRectF(QPointF(0, 0), pixsize)
        pixrect.moveCenter(rect.center())

        painter.save()
        painter.setPen(QPen(QColor(0, 0, 0, 50), 3))
        painter.drawRoundedRect(pixrect, 2, 2)
        painter.setRenderHint(QPainter.SmoothPixmapTransform)
        source = QRectF(QPointF(0, 0), QSizeF(self._pixmap.size()))
        painter.drawPixmap(pixrect, self._pixmap, source)
        painter.restore()
Example #14
0
    def paint(self, painter, option, widget=0):
        if self._pixmap.isNull():
            return

        rect = self.contentsRect()
        pixsize = QSizeF(self._pixmap.size())
        aspectmode = (Qt.KeepAspectRatio
                      if self._keepAspect else Qt.IgnoreAspectRatio)
        pixsize.scale(rect.size(), aspectmode)
        pixrect = QRectF(QPointF(0, 0), pixsize)
        pixrect.moveCenter(rect.center())

        painter.save()
        painter.setPen(QPen(QColor(0, 0, 0, 50), 3))
        painter.drawRoundedRect(pixrect, 2, 2)
        painter.setRenderHint(QPainter.SmoothPixmapTransform)
        source = QRectF(QPointF(0, 0), QSizeF(self._pixmap.size()))
        painter.drawPixmap(pixrect, self._pixmap, source)
        painter.restore()
Example #15
0
class LegendGradient(QGraphicsWidget):
    """Gradient widget.

    A gradient square bar that can be used to display continuous values.

    Parameters
    ----------
    palette : iterable[QColor]
    parent : QGraphicsWidget
    orientation : Qt.Orientation

    Notes
    -----
    .. note:: While the gradient does support any number of colors, any more
        than 3 is not very readable. This should not be a problem, since Orange
        only implements 2 or 3 colors.

    """

    # Default sizes (assume gradient is vertical by default)
    GRADIENT_WIDTH = 20
    GRADIENT_HEIGHT = 150
    _size_hint = QSizeF(GRADIENT_WIDTH, GRADIENT_HEIGHT)

    def __init__(self, palette, parent, orientation):
        super().__init__(parent)

        self.__gradient = QLinearGradient()
        num_colors = len(palette)
        for idx, stop in enumerate(palette):
            self.__gradient.setColorAt(idx * (1. / (num_colors - 1)), stop)

        # We need to tell the gradient where it's start and stop points are
        self.__gradient.setStart(QPointF(0, 0))
        if orientation == Qt.Vertical:
            final_stop = QPointF(0, self.GRADIENT_HEIGHT)
        else:
            final_stop = QPointF(self.GRADIENT_HEIGHT, 0)
        self.__gradient.setFinalStop(final_stop)

        # Get the appropriate rectangle dimensions based on orientation
        if orientation == Qt.Vertical:
            width, height = self.GRADIENT_WIDTH, self.GRADIENT_HEIGHT
        elif orientation == Qt.Horizontal:
            width, height = self.GRADIENT_HEIGHT, self.GRADIENT_WIDTH

        self.__rect_item = QGraphicsRectItem(0, 0, width, height, self)
        self.__rect_item.setPen(QPen(QColor(0, 0, 0, 0)))
        self.__rect_item.setBrush(QBrush(self.__gradient))
        self._size_hint = QSizeF(self.__rect_item.boundingRect().size())

    def sizeHint(self, size_hint, size_constraint=None, *args, **kwargs):
        return self._size_hint
    def paint(self, painter, option, widget=0):
        if self._pixmap.isNull():
            return

        rect = self.contentsRect()
        pixsize = QSizeF(self._pixmap.size())
        aspectmode = (Qt.KeepAspectRatio if self._keepAspect else Qt.IgnoreAspectRatio)

        if self._crop:
            height, width = pixsize.height(), pixsize.width()

            diff = abs(height - width)
            if height > width:
                y, x = diff / 2, 0
                h, w = height - diff, width
            else:
                x, y = diff / 2, 0
                w, h = width - diff, height

            source = QRectF(x, y, w, h)
            pixrect = QRectF(QPointF(0, 0), rect.size())

        else:
            source = QRectF(QPointF(0, 0), pixsize)
            pixsize.scale(rect.size(), aspectmode)
            pixrect = QRectF(QPointF(0, 0), pixsize)

        if self._subset:
            painter.setOpacity(1.0)
        else:
            painter.setOpacity(0.35)

        pixrect.moveCenter(rect.center())
        painter.save()
        painter.setPen(QPen(QColor(0, 0, 0, 50), 3))
        painter.drawRoundedRect(pixrect, 2, 2)
        painter.setRenderHint(QPainter.SmoothPixmapTransform)

        painter.drawPixmap(pixrect, self._pixmap, source)
        painter.restore()
Example #17
0
    def _resizeToFit(self):
        widget = self.__centralWidget
        size = self.__viewportContentSize()
        vprect = self.viewport().geometry()
        vprect.setSize(size)
        margins = self.viewportMargins()
        vprect = vprect.marginsRemoved(margins)

        viewrect = self.mapToScene(vprect).boundingRect()
        targetsize = viewrect.size()
        maxsize = widget.maximumSize()
        minsize = widget.minimumSize()
        targetsize = targetsize.expandedTo(minsize).boundedTo(maxsize)
        sh = widget.effectiveSizeHint(Qt.PreferredSize)
        policy = widget.sizePolicy()
        vpolicy = policy.verticalPolicy()
        hpolicy = policy.horizontalPolicy()

        if not self.__fitInView:
            widget.resize(sh.expandedTo(minsize).boundedTo(maxsize))
            return

        width = adjusted_size(
            sh.width(), targetsize.width(), minsize.width(),
            maxsize.width(), hpolicy)
        height = adjusted_size(
            sh.height(), targetsize.height(), minsize.height(),
            maxsize.height(), vpolicy)

        if policy.hasHeightForWidth():
            constr = QSizeF(width, -1)
            height = adjusted_size(
                widget.effectiveSizeHint(Qt.PreferredSize, constr).height(),
                targetsize.height(),
                widget.effectiveSizeHint(Qt.MinimumSize, constr).height(),
                widget.effectiveSizeHint(Qt.MaximumSize, constr).height(),
                QSizePolicy.Fixed
            )
        widget.resize(QSizeF(width, height))
    def __gridlayout(self):
        assert self.__layoutMode == GraphicsThumbnailGrid.FixedColumnCount

        width = (self.size().width() -
                 self.__columnCount * 10) / self.__columnCount
        height = (self.size().height() -
                  self.__rowCount * 10) / self.__rowCount
        item_size = min(width, height)

        for item in self.__thumbnails:
            item.setThumbnailSize(QSizeF(item_size, item_size))

        self.__relayoutGrid(self.__columnCount)
    def __gridlayout(self):
        assert self.__layoutMode == GraphicsThumbnailGrid.FixedColumnCount

        width = ((self.size().width() - self.__columnCount * 10) /
                self.__columnCount)
        height = (self.size().height() - self.__rowCount * 10) / self.__rowCount

        for item in self.__thumbnails:
            label_size = item.label.height() + 1 if item.label is not None else 0
            item_size = min(width, height - label_size)
            item.setThumbnailSize(QSizeF(item_size, item_size))

        self.__relayoutGrid(self.__columnCount)
 def sizeHint(self, which, constraint=QSizeF()):
     if which == Qt.PreferredSize:
         doc = self.document()
         textwidth = doc.textWidth()
         if textwidth != constraint.width():
             cloned = doc.clone(self)
             cloned.setTextWidth(constraint.width())
             sh = cloned.size()
             cloned.deleteLater()
         else:
             sh = doc.size()
         return sh
     else:
         return super().sizeHint(which, constraint)
Example #21
0
    def defaultTextGeometry(self, point):
        """
        Return the default text geometry. Used in case the user single
        clicked in the scene.

        """
        font = self.annotation_item.font()
        metrics = QFontMetrics(font)
        spacing = metrics.lineSpacing()
        margin = self.annotation_item.document().documentMargin()

        rect = QRectF(QPointF(point.x(), point.y() - spacing - margin),
                      QSizeF(150, spacing + 2 * margin))
        return rect
Example #22
0
 def sizeHint(self, which: Qt.SizeHint, constraint=QSizeF()) -> QSizeF:
     """Reimplemented."""
     if which == Qt.PreferredSize:
         sh = self.__naturalsh()
         if self.__orientation == Qt.Vertical:
             if 0 < constraint.height() < sh.height():
                 sh = scaled(sh, constraint, Qt.KeepAspectRatioByExpanding)
         else:
             sh = sh.transposed()
             if 0 < constraint.width() < sh.width():
                 sh = scaled(sh, constraint, Qt.KeepAspectRatioByExpanding)
     else:
         sh = super().sizeHint(which, constraint)
     return sh
Example #23
0
 def __init__(self, graph, scene):
     QGraphicsObject.__init__(self)
     if scene:
         scene.addItem(self)
     self.graph = graph
     self.curves = []
     self.items = {}
     self.attributes = []
     self.point_attrs = {}
     self.point_vals = {}
     self.default_values = {
         PointColor: Qt.black,
         PointSize: 8,
         PointSymbol: OWPoint.Ellipse
     }
     self.box_rect = QRectF()
     self.setFiltersChildEvents(True)
     self.setFlag(self.ItemHasNoContents, True)
     self.mouse_down = False
     self._orientation = Qt.Vertical
     self.max_size = QSizeF()
     self._floating = True
     self._floating_animation = None
     self._mouse_down_pos = QPointF()
Example #24
0
    def __init__(self,
                 parent=None,
                 direction=Qt.LeftToRight,
                 node=None,
                 icon=None,
                 iconSize=None,
                 **args):
        super().__init__(parent, **args)
        self.setAcceptedMouseButtons(Qt.NoButton)
        self.__direction = direction

        self.setLayout(QGraphicsLinearLayout(Qt.Horizontal))

        # Set the maximum size, otherwise the layout can't grow beyond its
        # sizeHint (and we need it to grow so the widget can grow and keep the
        # contents centered vertically.
        self.layout().setMaximumSize(QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX))

        self.setSizePolicy(QSizePolicy.MinimumExpanding,
                           QSizePolicy.MinimumExpanding)

        self.__iconSize = iconSize or QSize(64, 64)
        self.__icon = icon

        self.__iconItem = QGraphicsPixmapItem(self)
        self.__iconLayoutItem = GraphicsItemLayoutItem(item=self.__iconItem)

        self.__channelLayout = QGraphicsGridLayout()
        self.channelAnchors = []

        if self.__direction == Qt.LeftToRight:
            self.layout().addItem(self.__iconLayoutItem)
            self.layout().addItem(self.__channelLayout)
            channel_alignemnt = Qt.AlignRight

        else:
            self.layout().addItem(self.__channelLayout)
            self.layout().addItem(self.__iconLayoutItem)
            channel_alignemnt = Qt.AlignLeft

        self.layout().setAlignment(self.__iconLayoutItem, Qt.AlignCenter)
        self.layout().setAlignment(self.__channelLayout,
                                   Qt.AlignVCenter | channel_alignemnt)

        self.node: Optional[SchemeNode] = None
        self.channels: Union[List[InputSignal], List[OutputSignal]] = []
        if node is not None:
            self.setSchemeNode(node)
 def sizeHint(self, which: Qt.SizeHint, constraint=QSizeF(-1, -1)) -> QSizeF:
     if which == Qt.PreferredSize:
         brect = self.item.boundingRect()
         brect = self.item.mapRectToParent(brect)
         scale = self.__transform
         size = brect.size()
         if scale is not None:
             # undo the scaling
             sx, sy = self.__scale
             size = QSizeF(float(Fraction(size.width()) / sx),
                           float(Fraction(size.height()) / sy))
         if constraint != QSizeF(-1, -1):
             size = scaled(size, constraint, self.__aspectMode)
         return size
     else:
         return QSizeF()
Example #26
0
    def setupScene(self):
        self.error()
        if self.data:
            attr = self.stringAttrs[self.smilesAttr]
            titleAttr = self.allAttrs[self.titleAttr]
            assert self.thumbnailView.count() == 0
            size = QSizeF(self.imageSize, self.imageSize)

            for i, inst in enumerate(self.data):
                if not numpy.isfinite(inst[attr]):  # skip missing
                    continue

                smiles = str(inst[attr])
                title = str(inst[titleAttr])

                thumbnail = GraphicsThumbnailWidget(QPixmap(), title=title)
                thumbnail.setThumbnailSize(size)
                thumbnail.setToolTip(smiles)
                thumbnail.instance = inst
                self.thumbnailView.addThumbnail(thumbnail)

                if self.check_smiles(smiles):
                    pixmap = self.pixmap_from_smiles(smiles)
                    thumbnail.setPixmap(pixmap)
                    self._successcount += 1

                else:
                    pixmap = QPixmap()
                    thumbnail.setPixmap(pixmap)
                    thumbnail.setToolTip(thumbnail.toolTip() +
                                         "\nInvalid SMILES")
                    self._errcount += 1

                future = Future()
                future.set_result(pixmap)
                future._reply = None

                self.items.append(_ImageItem(i, thumbnail, smiles, future))

            if any(it.future is not None and not it.future.done()
                   for it in self.items):
                self.info.setText("Retrieving...\n")
            else:
                self._updateStatus()
Example #27
0
    def __doLayout(self, rect: QRectF) -> Iterable[QRectF]:
        x = y = 0
        rowheight = 0
        width = rect.width()
        spacing_x, spacing_y = self.__spacing
        first_in_row = True
        rows: List[List[QRectF]] = [[]]

        def break_():
            nonlocal x, y, rowheight, first_in_row
            y += rowheight + spacing_y
            x = 0
            rowheight = 0
            first_in_row = True
            rows.append([])

        items = [
            _FlowLayoutItem(item=item, geom=QRectF(), size=QSizeF())
            for item in self.__items
        ]

        for flitem in items:
            item = flitem.item
            sh = item.effectiveSizeHint(Qt.PreferredSize)
            if x + sh.width() > width and not first_in_row:
                break_()
            r = QRectF(rect.x() + x, rect.y() + y, sh.width(), sh.height())
            flitem.geom = r
            flitem.size = sh
            flitem.row = len(rows) - 1
            rowheight = max(rowheight, sh.height())
            x += sh.width() + spacing_x
            first_in_row = False
            rows[-1].append(flitem.geom)

        alignment = Qt.AlignVCenter | Qt.AlignLeft
        for flitem in items:
            row = rows[flitem.row]
            row_rect = reduce(QRectF.united, row, QRectF())
            if row_rect.isEmpty():
                continue
            flitem.geom = qrect_aligned_to(flitem.geom, row_rect,
                                           alignment & Qt.AlignVertical_Mask)
        return [fli.geom for fli in items]
Example #28
0
    def item_at(self, pos, type_or_tuple=None, buttons=0):
        """Return the item at `pos` that is an instance of the specified
        type (`type_or_tuple`). If `buttons` (`Qt.MouseButtons`) is given
        only return the item if it is the top level item that would
        accept any of the buttons (`QGraphicsItem.acceptedMouseButtons`).

        """
        rect = QRectF(pos, QSizeF(1, 1))
        items = self.items(rect)

        if buttons:
            items = itertools.dropwhile(
                lambda item: not item.acceptedMouseButtons() & buttons, items)
            items = list(items)[:1]

        if type_or_tuple:
            items = [i for i in items if isinstance(i, type_or_tuple)]

        return items[0] if items else None
Example #29
0
    def sizeHint(self, which, constraint=QRectF()):
        # type: (Qt.SizeHint, QSizeF) -> QSizeF
        pw = 1.
        sh = QSizeF()
        if which == Qt.MinimumSize:
            sh = QSizeF(pw, pw)
        elif which == Qt.PreferredSize:
            sh = QSizeF(pw, 30.)
        elif which == Qt.MaximumSize:
            sh = QSizeF(pw, QWIDGETSIZE_MAX)

        if self.__orientation == Qt.Horizontal:
            sh.transpose()  # Qt4 compatible
        return sh
Example #30
0
 def export(self, filename=None):
     pw = QPdfWriter(filename)
     dpi = QApplication.desktop().logicalDpiX()
     pw.setResolution(dpi)
     pw.setPageMargins(QMarginsF(0, 0, 0, 0))
     pw.setPageSizeMM(QSizeF(self.getTargetRect().size()) / dpi * 25.4)
     painter = QPainter(pw)
     try:
         self.setExportMode(True, {'antialias': True,
                                   'background': self.background,
                                   'painter': painter})
         painter.setRenderHint(QPainter.Antialiasing, True)
         if QtCore.QT_VERSION >= 0x050D00:
             painter.setRenderHint(QPainter.LosslessImageRendering, True)
         self.getScene().render(painter,
                                QRectF(self.getTargetRect()),
                                QRectF(self.getSourceRect()))
     finally:
         self.setExportMode(False)
     painter.end()
Example #31
0
def render_drop_shadow_frame(pixmap, shadow_rect, shadow_color, offset, radius,
                             rect_fill_color):
    pixmap.fill(QColor(0, 0, 0, 0))
    scene = QGraphicsScene()
    rect = QGraphicsRectItem(shadow_rect)
    rect.setBrush(QColor(rect_fill_color))
    rect.setPen(QPen(Qt.NoPen))
    scene.addItem(rect)
    effect = QGraphicsDropShadowEffect(color=shadow_color,
                                       blurRadius=radius,
                                       offset=offset)

    rect.setGraphicsEffect(effect)
    scene.setSceneRect(QRectF(QPointF(0, 0), QSizeF(pixmap.size())))
    painter = QPainter(pixmap)
    scene.render(painter)
    painter.end()
    scene.clear()
    scene.deleteLater()
    return pixmap
Example #32
0
    def __init__(self,
                 pixmap,
                 parentItem=None,
                 crop=False,
                 in_subset=True,
                 add_label=False,
                 text="",
                 **kwargs):
        super().__init__(parentItem, **kwargs)
        self.setFocusPolicy(Qt.StrongFocus)
        self._size = QSizeF()

        layout = QGraphicsLinearLayout(Qt.Vertical, self)
        layout.setSpacing(1)
        layout.setContentsMargins(5, 5, 5, 5)
        self.setContentsMargins(0, 0, 0, 0)

        self.pixmapWidget = GraphicsPixmapWidget(pixmap, self)
        self.pixmapWidget.setCrop(crop)
        self.pixmapWidget.setSubset(in_subset)
        self.selectionBrush = DEFAULT_SELECTION_BRUSH
        self.selectionPen = DEFAULT_SELECTION_PEN

        layout.addItem(self.pixmapWidget)

        self.label = None
        if add_label:
            l1 = ElidedLabel(text)
            l1.setStyleSheet("background-color: rgba(255, 255, 255, 10);")
            l1.setAlignment(Qt.AlignCenter)
            l1.setFixedHeight(16)

            self.label = l1
            gs = QGraphicsScene()
            w = gs.addWidget(l1)
            layout.addItem(w)

        layout.setAlignment(self.pixmapWidget, Qt.AlignCenter)
        self.setLayout(layout)

        self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
 def sizeHint(self, which, constraint=QSizeF(-1, -1)) -> QSizeF:
     if which == Qt.PreferredSize:
         sh = QSizeF(self.__pixmap.size())
         if self.__scaleContents:
             sh = scaled(sh, constraint, self.__aspectMode)
         return sh
     elif which == Qt.MinimumSize:
         if self.__scaleContents:
             return QSizeF(0, 0)
         else:
             return QSizeF(self.__pixmap.size())
     elif which == Qt.MaximumSize:
         if self.__scaleContents:
             return QSizeF()
         else:
             return QSizeF(self.__pixmap.size())
     else:
         # Qt.MinimumDescent
         return QSizeF()
Example #34
0
    def mouseReleaseEvent(self, event):
        QGraphicsScene.mouseReleaseEvent(self, event)

        if event.button() == Qt.LeftButton:
            modifiers = event.modifiers()
            path = QPainterPath()

            # the mouse was moved
            if self.selectionRect:
                path.addRect(self.selectionRect.rect())
                self.removeItem(self.selectionRect)
                self.selectionRect = None

            # the mouse was only clicked - create a selection area of 1x1 size
            else:
                rect = QRectF(event.buttonDownScenePos(Qt.LeftButton),
                              QSizeF(1., 1.)).intersected(self.sceneRect())
                path.addRect(rect)

            self.setSelectionArea(path)
            self.selectionChanged.emit(set(self.selectedItems()), modifiers)
Example #35
0
 def __init__(self, graph, scene):
     QGraphicsObject.__init__(self)
     if scene:
         scene.addItem(self)
     self.graph = graph
     self.curves = []
     self.items = {}
     self.attributes = []
     self.point_attrs = {}
     self.point_vals = {}
     self.default_values = {
                            PointColor : Qt.black,
                            PointSize : 8,
                            PointSymbol : OWPoint.Ellipse
                            }
     self.box_rect = QRectF()
     self.setFiltersChildEvents(True)
     self.setFlag(self.ItemHasNoContents, True)
     self.mouse_down = False
     self._orientation = Qt.Vertical
     self.max_size = QSizeF()
     self._floating = True
     self._floating_animation = None
     self._mouse_down_pos = QPointF()
Example #36
0
class OWLegend(QGraphicsObject):
    """
        A legend for :obj:`.OWPlot`.

        Its items are arranged into a hierarchy by `category`. This is useful when points differ in more than one attribute.
        In such a case, there can be one category for point color and one for point shape. Usually the category name
        will be the name of the attribute, while the item's title will be the value.

        Arbitrary categories can be created, for an example see :meth:`.OWPlot.update_axes`, which creates a special category
        for unused axes.
        decimals
        .. image:: files/legend-categories.png

        In the image above, `type` and `milk` are categories with 7 and 2 possible values, respectively.

    """
    def __init__(self, graph, scene):
        QGraphicsObject.__init__(self)
        if scene:
            scene.addItem(self)
        self.graph = graph
        self.curves = []
        self.items = {}
        self.attributes = []
        self.point_attrs = {}
        self.point_vals = {}
        self.default_values = {
                               PointColor : Qt.black,
                               PointSize : 8,
                               PointSymbol : OWPoint.Ellipse
                               }
        self.box_rect = QRectF()
        self.setFiltersChildEvents(True)
        self.setFlag(self.ItemHasNoContents, True)
        self.mouse_down = False
        self._orientation = Qt.Vertical
        self.max_size = QSizeF()
        self._floating = True
        self._floating_animation = None
        self._mouse_down_pos = QPointF()

    def clear(self):
        """
            Removes all items from the legend
        """
        for lst in self.items.values():
            for i in lst:
                i.setParentItem(None)
                if self.scene():
                    self.scene().removeItem(i)
        self.items = {}
        self.update_items()


    def add_curve(self, curve):
        """
            Adds a legend item with the same point symbol and name as ``curve``.

            If the curve's name contains the equal sign (=), it is split at that sign. The first part of the curve
            is a used as the category, and the second part as the value.
        """
        i = curve.name.find('=')
        if i == -1:
            cat = ''
            name = curve.name
        else:
            cat = curve.name[:i]
            name = curve.name[i+1:]
        self.add_item(cat, name, curve.point_item(0, 0, 0))

    def add_item(self, category, value, point):
        """
            Adds an item with title ``value`` and point symbol ``point`` to the specified ``category``.
        """
        if category not in self.items:
            self.items[category] = [OWLegendTitle(category, self)]
        self.items[category].append(OWLegendItem(str(value), point, self))
        self.update_items()

    def add_color_gradient(self, title, values):
        if len(values) < 2:
            # No point in showing a gradient with less that two values
            return
        if title in self.items:
            self.remove_category(title)
        item = OWLegendGradient(self.graph.contPalette, [str(v) for v in values], self)
        self.items[title] = [OWLegendTitle(title, self), item]
        self.update_items()

    def remove_category(self, category):
        """
            Removes ``category`` and all items that belong to it.
        """
        if category not in self.items:
            return
        if self.scene():
            for item in self.items[category]:
                self.scene().removeItem(item)
        del self.items[category]

    def update_items(self):
        """
            Updates the legend, repositioning the items according to the legend's orientation.
        """
        self.box_rect = QRectF()
        x = y = 0

        for lst in self.items.values():
            for item in lst:
                if hasattr(item, 'text_item'):
                    item.text_item.setDefaultTextColor(self.graph.color(OWPalette.Text))
                if hasattr(item, 'rect_item'):
                    item.rect_item.setBrush(self.graph.color(OWPalette.Canvas))
                if hasattr(item, 'set_orientation'):
                    item.set_orientation(self._orientation)

        if self._orientation == Qt.Vertical:
            for lst in self.items.values():
                for item in lst:
                    if self.max_size.height() and y and y + item.boundingRect().height() > self.max_size.height():
                        y = 0
                        x = x + item.boundingRect().width()
                    self.box_rect = self.box_rect | item.boundingRect().translated(x, y)
                    move_item_xy(item, x, y, self.graph.animate_plot)
                    y = y + item.boundingRect().height()
        elif self._orientation == Qt.Horizontal:
            for lst in self.items.values():
                max_h = max(item.boundingRect().height() for item in lst)
                for item in lst:
                    if self.max_size.width() and x and x + item.boundingRect().width() > self.max_size.width():
                        x = 0
                        y = y + max_h
                    self.box_rect = self.box_rect | item.boundingRect().translated(x, y)
                    move_item_xy(item, x, y, self.graph.animate_plot)
                    x = x + item.boundingRect().width()
                if lst:
                    x = 0
                    y = y + max_h

    def mouseMoveEvent(self, event):
        self.graph.notify_legend_moved(event.scenePos())
        if self._floating:
            p = event.scenePos() - self._mouse_down_pos
            if self._floating_animation and self._floating_animation.state() == QPropertyAnimation.Running:
                self.set_pos_animated(p)
            else:
                self.setPos(p)
        event.accept()

    def mousePressEvent(self, event):
        self.setCursor(Qt.ClosedHandCursor)
        self.mouse_down = True
        self._mouse_down_pos = event.scenePos() - self.pos()
        event.accept()

    def mouseReleaseEvent(self, event):
        self.unsetCursor()
        self.mouse_down = False
        self._mouse_down_pos = QPointF()
        event.accept()

    def boundingRect(self):
        return self.box_rect

    def paint(self, painter, option, widget=None):
        pass

    def set_orientation(self, orientation):
        """
            Sets the legend's orientation to ``orientation``.
        """
        self._orientation = orientation
        self.update_items()

    def orientation(self):
        return self._orientation

    def set_pos_animated(self, pos):
        if (self.pos() - pos).manhattanLength() < 6 or not self.graph.animate_plot:
            self.setPos(pos)
        else:
            t = 250
            if self._floating_animation and self._floating_animation.state() == QPropertyAnimation.Running:
                t = t - self._floating_animation.currentTime()
                self._floating_animation.stop()
            self._floating_animation = QPropertyAnimation(self, 'pos')
            self._floating_animation.setEndValue(pos)
            self._floating_animation.setDuration(t)
            self._floating_animation.start(QPropertyAnimation.KeepWhenStopped)

    def set_floating(self, floating, pos=None):
        """
            If floating is ``True``, the legend can be dragged with the mouse.
            Otherwise, it's fixed in its position.

            If ``pos`` is specified, the legend is moved there.
        """
        if floating == self._floating:
            return
        self._floating = floating
        if pos:
            if floating:
                self.set_pos_animated(pos - self._mouse_down_pos)
            else:
                self.set_pos_animated(pos)