Пример #1
0
 def paint(self, painter, option, widget=None):
     # type: (QPainter, QStyleOptionGraphicsItem, Optional[QWidget]) -> None
     palette = option.palette  # type: QPalette
     role = QPalette.WindowText
     if widget is not None:
         role = widget.foregroundRole()
     color = palette.color(role)
     painter.setPen(QPen(color, 1))
     rect = self.contentsRect()
     center = rect.center()
     if self.__orientation == Qt.Vertical:
         p1 = QPointF(center.x(), rect.top())
         p2 = QPointF(center.x(), rect.bottom())
     elif self.__orientation == Qt.Horizontal:
         p1 = QPointF(rect.left(), center.y())
         p2 = QPointF(rect.right(), center.y())
     else:
         assert False
     painter.drawLine(p1, p2)
 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
Пример #3
0
def qrect_aligned_to(
        rect_a: QRectF, rect_b: QRectF, alignment: Qt.Alignment) -> QRectF:
    res = QRectF(rect_a)
    valign = alignment & Qt.AlignVertical_Mask
    halign = alignment & Qt.AlignHorizontal_Mask
    if valign == Qt.AlignTop:
        res.moveTop(rect_b.top())
    if valign == Qt.AlignVCenter:
        res.moveCenter(QPointF(res.center().x(), rect_b.center().y()))
    if valign == Qt.AlignBottom:
        res.moveBottom(rect_b.bottom())

    if halign == Qt.AlignLeft:
        res.moveLeft(rect_b.left())
    if halign == Qt.AlignHCenter:
        res.moveCenter(QPointF(rect_b.center().x(), res.center().y()))
    if halign == Qt.AlignRight:
        res.moveRight(rect_b.right())
    return res
Пример #4
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()
Пример #5
0
def path_link_disabled(basepath):
    """
    Return a QPainterPath 'styled' to indicate a 'disabled' link.

    A disabled link is displayed with a single disconnection symbol in the
    middle (--||--)

    Parameters
    ----------
    basepath : QPainterPath
        The base path (a simple curve spine).

    Returns
    -------
    path : QPainterPath
        A 'styled' link path
    """
    segmentlen = basepath.length()
    px = 5

    if segmentlen < 10:
        return QPainterPath(basepath)

    t = (px / 2) / segmentlen
    p1, _ = qpainterpath_simple_split(basepath, 0.50 - t)
    _, p2 = qpainterpath_simple_split(basepath, 0.50 + t)

    angle = -basepath.angleAtPercent(0.5) + 90
    angler = math.radians(angle)
    normal = QPointF(math.cos(angler), math.sin(angler))

    end1 = p1.currentPosition()
    start2 = QPointF(p2.elementAt(0).x, p2.elementAt(0).y)
    p1.moveTo(start2.x(), start2.y())
    p1.addPath(p2)

    def QPainterPath_addLine(path, line):
        path.moveTo(line.p1())
        path.lineTo(line.p2())

    QPainterPath_addLine(p1, QLineF(end1 - normal * 3, end1 + normal * 3))
    QPainterPath_addLine(p1, QLineF(start2 - normal * 3, start2 + normal * 3))
    return p1
Пример #6
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)
Пример #7
0
    def test_saved_selection(self):
        graph = self.widget.graph
        self.send_signal(self.widget.Inputs.data, self.data)
        graph._update_selection(QPointF(0, 6), QPointF(0, 5.5), 1)
        selected1 = self.get_output(self.widget.Outputs.selected_data)
        self.assertEqual(len(selected1), 5)

        with patch("AnyQt.QtWidgets.QApplication.keyboardModifiers",
                   lambda: Qt.ShiftModifier):
            graph._update_selection(QPointF(6, 6), QPointF(6, 5.5), 1)
        selected2 = self.get_output(self.widget.Outputs.selected_data)
        self.assertEqual(len(selected2), 13)

        settings = self.widget.settingsHandler.pack_data(self.widget)
        widget = self.create_widget(OWViolinPlot, stored_settings=settings)
        self.send_signal(widget.Inputs.data, self.data, widget=widget)
        selected3 = self.get_output(widget.Outputs.selected_data,
                                    widget=widget)
        self.assert_table_equal(selected2, selected3)
Пример #8
0
 def test_select_polygon_as_rectangle(self):
     # rectangle and a polygon need to give the same results
     self.send_signal("Data", self.whitelight)
     self.widget.imageplot.select_square(QPointF(5, 5), QPointF(15, 10), False)
     out = self.get_output("Selection")
     self.widget.imageplot.select_polygon([QPointF(5, 5), QPointF(15, 5), QPointF(15, 10),
                                           QPointF(5, 10), QPointF(5, 5)], False)
     outpoly = self.get_output("Selection")
     self.assertEqual(list(out), list(outpoly))
Пример #9
0
    def _orthonormal_line(x, y, color, width):
        # https://en.wikipedia.org/wiki/Deming_regression, with δ=0.
        pen = pg.mkPen(color=color, width=width)
        xm = np.mean(x)
        ym = np.mean(y)
        sxx, sxy, _, syy = np.cov(x, y, ddof=1).flatten()

        if sxy != 0:  # also covers sxx != 0 and syy != 0
            slope = (syy - sxx + np.sqrt((syy - sxx) ** 2 + 4 * sxy ** 2)) \
                    / (2 * sxy)
            intercept = ym - slope * xm
            xmin = x.min()
            return pg.InfiniteLine(QPointF(xmin, xmin * slope + intercept),
                                   np.degrees(np.arctan(slope)), pen)
        elif (sxx == 0) == (syy == 0):  # both zero or non-zero -> can't draw
            return None
        elif sxx != 0:
            return pg.InfiniteLine(QPointF(x.min(), ym), 0, pen)
        else:
            return pg.InfiniteLine(QPointF(xm, y.min()), 90, pen)
Пример #10
0
def qpainterpath_simple_split(path, t):
    # type: (QPainterPath, float) -> Tuple[QPainterPath, QPainterPath]
    """
    Split a QPainterPath defined simple curve.

    The path must be either empty or composed of a single LineToElement or
    CurveToElement.

    Parameters
    ----------
    path : QPainterPath

    t : float
        Point where to split specified as a percentage along the path

    Returns
    -------
    splitpath: Tuple[QPainterPath, QPainterPath]
        A pair of QPainterPaths
    """
    assert path.elementCount() > 0
    el0 = path.elementAt(0)
    assert el0.type == QPainterPath.MoveToElement
    if path.elementCount() == 1:
        p1 = QPainterPath()
        p1.moveTo(el0.x, el0.y)
        return p1, QPainterPath(p1)

    el1 = path.elementAt(1)
    if el1.type == QPainterPath.LineToElement:
        pointat = path.pointAtPercent(t)
        l1 = QLineF(el0.x, el0.y, pointat.x(), pointat.y())
        l2 = QLineF(pointat.x(), pointat.y(), el1.x, el1.y)
        p1 = QPainterPath()
        p2 = QPainterPath()
        p1.moveTo(l1.p1())
        p1.lineTo(l1.p2())
        p2.moveTo(l2.p1())
        p2.lineTo(l2.p2())
        return p1, p2
    elif el1.type == QPainterPath.CurveToElement:
        c0, c1, c2, c3 = el0, el1, path.elementAt(2), path.elementAt(3)
        assert all(el.type == QPainterPath.CurveToDataElement
                   for el in [c2, c3])
        cp = [QPointF(el.x, el.y) for el in [c0, c1, c2, c3]]
        first, second = bezier_subdivide(cp, t)
        p1, p2 = QPainterPath(), QPainterPath()
        p1.moveTo(first[0])
        p1.cubicTo(*first[1:])
        p2.moveTo(second[0])
        p2.cubicTo(*second[1:])
        return p1, p2
    else:
        assert False
Пример #11
0
    def __init__(self, parent=None, text=""):
        super().__init__(parent)
        self.setAcceptHoverEvents(True)
        self.setPen(QPen(Qt.NoPen))

        self.text = QGraphicsTextItem(self)
        layout = self.text.document().documentLayout()
        layout.documentSizeChanged.connect(self._onLayoutChanged)

        self._text = text
        self._anchor = QPointF()
Пример #12
0
 def __init__(self, *args, **kwargs) -> None:
     super().__init__(*args, **kwargs)
     palette = self.palette()
     ds = QGraphicsDropShadowEffect(parent=self,
                                    objectName="sticky-view-shadow",
                                    color=palette.color(
                                        QPalette.Foreground),
                                    blurRadius=15,
                                    offset=QPointF(0, 0),
                                    enabled=True)
     self.setGraphicsEffect(ds)
Пример #13
0
 def __init__(self, text, x, y, align, bold = 0, color = None, brushColor = None, size=None):
     orangeqt.PlotItem.__init__(self)
     self.setFlag(QGraphicsItem.ItemIgnoresTransformations, True)
     self._item = QGraphicsTextItem(text, parent=self)
     self._data_point = QPointF(x,y)
     f = self._item.font()
     f.setBold(bold)
     if size:
         f.setPointSize(size)
     self._item.setFont(f)
     self._item.setPos(x, y)
Пример #14
0
    def test_selection(self):
        selection_handler = Mock()

        view_box = self.plot.getViewBox()
        self.plot.selectionChanged.connect(selection_handler)

        event = Mock()
        event.button.return_value = Qt.LeftButton
        event.buttonDownPos.return_value = QPointF(10, 0)
        event.pos.return_value = QPointF(30, 0)
        event.isFinish.return_value = True

        # select before data is sent
        view_box.mouseDragEvent(event)

        # set data
        x_data = np.arange(5)
        pos_y_data = [(np.arange(5) - 1, np.arange(5))]
        neg_y_data = [(np.arange(5), np.arange(5) + 1)]
        labels = [a.name for a in self.housing.domain.attributes]
        self.plot.set_data(x_data, pos_y_data, neg_y_data, "", "", labels,
                           labels, self.housing)

        # select after data is sent
        view_box.mouseDragEvent(event)
        selection_handler.assert_called_once()

        # select other instances
        event.buttonDownPos.return_value = QPointF(40, 0)
        event.pos.return_value = QPointF(60, 0)

        selection_handler.reset_mock()
        view_box.mouseDragEvent(event)
        selection_handler.assert_called_once()
        self.assertEqual(len(selection_handler.call_args[0][0]), 2)

        # click on the plot resets selection
        selection_handler.reset_mock()
        view_box.mouseClickEvent(event)
        selection_handler.assert_called_once()
        self.assertEqual(len(selection_handler.call_args[0][0]), 0)
Пример #15
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)

        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()
def qWheelScroll(
        widget: QWidget,
        buttons=Qt.NoButton,
        modifiers=Qt.NoModifier,
        pos=QPoint(),
        angleDelta=QPoint(0, 1),
):
    if pos.isNull():
        pos = widget.rect().center()
    globalPos = widget.mapToGlobal(pos)

    if angleDelta.y() >= angleDelta.x():
        qt4orient = Qt.Vertical
        qt4delta = angleDelta.y()
    else:
        qt4orient = Qt.Horizontal
        qt4delta = angleDelta.x()

    event = QWheelEvent(QPointF(pos), QPointF(globalPos), QPoint(), angleDelta,
                        qt4delta, qt4orient, buttons, modifiers)
    QApplication.sendEvent(widget, event)
Пример #17
0
    def test_selection_setting(self):
        widget = self.widget
        data = Table("iris.tab")
        self.send_signal(widget.Inputs.data, data)

        widget.select_area(
            1,
            QMouseEvent(QEvent.MouseButtonPress, QPointF(), Qt.LeftButton,
                        Qt.LeftButton, Qt.NoModifier))

        # Changing the data must reset the selection
        self.send_signal(widget.Inputs.data, Table("titanic"))
        self.assertFalse(bool(widget.selection))
        self.assertIsNone(self.get_output(widget.Outputs.selected_data))

        self.send_signal(widget.Inputs.data, data)
        self.assertFalse(bool(widget.selection))
        self.assertIsNone(self.get_output(widget.Outputs.selected_data))

        widget.select_area(
            1,
            QMouseEvent(QEvent.MouseButtonPress, QPointF(), Qt.LeftButton,
                        Qt.LeftButton, Qt.NoModifier))
        settings = self.widget.settingsHandler.pack_data(self.widget)

        # Setting data to None must reset the selection
        self.send_signal(widget.Inputs.data, None)
        self.assertFalse(bool(widget.selection))
        self.assertIsNone(self.get_output(widget.Outputs.selected_data))

        self.send_signal(widget.Inputs.data, data)
        self.assertFalse(bool(widget.selection))
        self.assertIsNone(self.get_output(widget.Outputs.selected_data))

        w = self.create_widget(OWMosaicDisplay, stored_settings=settings)
        self.assertFalse(bool(widget.selection))
        self.send_signal(w.Inputs.data, data, widget=w)
        self.assertEqual(w.selection, {1})
        self.assertIsNotNone(self.get_output(w.Outputs.selected_data,
                                             widget=w))
Пример #18
0
    def test_graphicspathobject(self):
        obj = GraphicsPathObject()
        path = QPainterPath()
        obj.setFlag(GraphicsPathObject.ItemIsMovable)

        path.addEllipse(20, 20, 50, 50)

        obj.setPath(path)
        self.assertEqual(obj.path(), path)

        self.assertTrue(obj.path() is not path,
                        msg="setPath stores the path not a copy")

        brect = obj.boundingRect()
        self.assertTrue(brect.contains(path.boundingRect()))

        with self.assertRaises(TypeError):
            obj.setPath("This is not a path")

        brush = QBrush(QColor("#ffbb11"))
        obj.setBrush(brush)

        self.assertEqual(obj.brush(), brush)

        self.assertTrue(obj.brush() is not brush,
                        "setBrush stores the brush not a copy")

        pen = QPen(QColor("#FFFFFF"), 1.4)
        obj.setPen(pen)

        self.assertEqual(obj.pen(), pen)

        self.assertTrue(obj.pen() is not pen,
                        "setPen stores the pen not a copy")

        brect = obj.boundingRect()
        self.assertGreaterEqual(area(brect), (50 + 1.4 * 2)**2)

        self.assertIsInstance(obj.shape(), QPainterPath)

        positions = []
        obj.positionChanged[QPointF].connect(positions.append)

        pos = QPointF(10, 10)
        obj.setPos(pos)

        self.assertEqual(positions, [pos])

        self.scene.addItem(obj)
        self.view.show()

        self.qWait()
Пример #19
0
    def test_plot_multiple_selection(self):
        self.send_signal(self.widget.Inputs.data, self.heart[:10])
        self.send_signal(self.widget.Inputs.background_data, self.heart)
        self.send_signal(self.widget.Inputs.model, self.rf_cls)
        self.wait_until_finished()

        event = Mock()
        event.button.return_value = Qt.LeftButton
        event.buttonDownPos.return_value = QPointF(10, 0)
        event.pos.return_value = QPointF(30, 0)
        event.isFinish.return_value = True
        self.widget.graph.getViewBox().mouseDragEvent(event)

        output = self.get_output(self.widget.Outputs.selected_data)
        self.assertEqual(len(output), 4)

        event.buttonDownPos.return_value = QPointF(40, 0)
        event.pos.return_value = QPointF(50, 0)
        self.widget.graph.getViewBox().mouseDragEvent(event)

        output = self.get_output(self.widget.Outputs.selected_data)
        self.assertEqual(len(output), 5)
    def test_selection_rect(self, mocked_mapToView: Mock):
        mocked_mapToView.side_effect = lambda x: x

        view_box: ViewBox = self.widget.graph.getViewBox()

        event = Mock()
        event.button.return_value = Qt.LeftButton
        event.buttonDownPos.return_value = QPointF(0, 5)
        event.pos.return_value = QPointF(0, 6)
        event.isFinish.return_value = True

        self.send_signal(self.widget.Inputs.data, self.data)
        view_box.mouseDragEvent(event)
        selected = self.get_output(self.widget.Outputs.selected_data)
        self.assertEqual(len(selected), 30)

        sel_rect = self.widget.graph._ViolinPlot__selection_rects[0]
        self.assertEqual(sel_rect.selection_rect.height(), 1)

        self.widget.controls.orientation_index.buttons[0].click()
        sel_rect = self.widget.graph._ViolinPlot__selection_rects[0]
        self.assertEqual(sel_rect.selection_rect.width(), 1)
Пример #21
0
    def __shadowPixmapFragments(self, pixmap_rect, shadow_rect):
        """
        Return a list of 8 QRectF fragments for drawing a shadow.
        """
        s_left, s_top, s_right, s_bottom = (
            shadow_rect.left(),
            shadow_rect.top(),
            shadow_rect.right(),
            shadow_rect.bottom(),
        )
        s_width, s_height = shadow_rect.width(), shadow_rect.height()
        p_width, p_height = pixmap_rect.width(), pixmap_rect.height()

        top_left = QRectF(0.0, 0.0, s_left, s_top)
        top = QRectF(s_left, 0.0, s_width, s_top)
        top_right = QRectF(s_right, 0.0, p_width - s_width, s_top)
        right = QRectF(s_right, s_top, p_width - s_right, s_height)
        right_bottom = QRectF(shadow_rect.bottomRight(),
                              pixmap_rect.bottomRight())
        bottom = QRectF(
            shadow_rect.bottomLeft(),
            pixmap_rect.bottomRight() - QPointF(p_width - s_right, 0.0),
        )
        bottom_left = QRectF(
            shadow_rect.bottomLeft() - QPointF(s_left, 0.0),
            pixmap_rect.bottomLeft() + QPointF(s_left, 0.0),
        )
        left = QRectF(pixmap_rect.topLeft() + QPointF(0.0, s_top),
                      shadow_rect.bottomLeft())
        return [
            top_left,
            top,
            top_right,
            right,
            right_bottom,
            bottom,
            bottom_left,
            left,
        ]
Пример #22
0
 def _regression_line(x, y, color, width, style=Qt.SolidLine):
     min_x, max_x = np.min(x), np.max(x)
     if min_x == max_x:
         return None
     slope, intercept, rvalue, _, _ = linregress(x, y)
     angle = np.degrees(np.arctan(slope))
     start_y = min_x * slope + intercept
     l_opts = dict(color=color, position=0.85,
                   rotateAxis=(1, 0), movable=True)
     return pg.InfiniteLine(
         pos=QPointF(min_x, start_y), angle=angle,
         pen=pg.mkPen(color=color, width=width, style=style),
         label=f"r = {rvalue:.2f}", labelOpts=l_opts)
Пример #23
0
def mouseMove(widget, buttons, modifier=Qt.NoModifier, pos=QPoint(), delay=-1):
    # type: (QWidget, Qt.MouseButtons, Qt.KeyboardModifier, QPoint, int) -> None
    """
    Like QTest.mouseMove, but with `buttons` and `modifier` parameters.

    Parameters
    ----------
    widget : QWidget
    buttons: Qt.MouseButtons
    modifier : Qt.KeyboardModifiers
    pos : QPoint
    delay : int
    """
    if pos.isNull():
        pos = widget.rect().center()
    me = QMouseEvent(QMouseEvent.MouseMove, QPointF(pos),
                     QPointF(widget.mapToGlobal(pos)), Qt.NoButton, buttons,
                     modifier)
    if delay > 0:
        QTest.qWait(delay)

    QCoreApplication.sendEvent(widget, me)
Пример #24
0
    def _create_violin(self, data: np.ndarray) -> Tuple[QPainterPath, float]:
        if self.__kde is None:
            x, p, max_density = np.zeros(1), np.zeros(1), 0
        else:
            x = np.linspace(data.min() - self.__bandwidth * 2,
                            data.max() + self.__bandwidth * 2, 1000)
            p = np.exp(self.__kde.score_samples(x.reshape(-1, 1)))
            max_density = p.max()
            p = scale_density(self.__scale, p, len(data), max_density)

        if self.__orientation == Qt.Vertical:
            pts = [QPointF(pi, xi) for xi, pi in zip(x, p)]
            pts += [QPointF(-pi, xi) for xi, pi in reversed(list(zip(x, p)))]
        else:
            pts = [QPointF(xi, pi) for xi, pi in zip(x, p)]
            pts += [QPointF(xi, -pi) for xi, pi in reversed(list(zip(x, p)))]
        pts += pts[:1]

        polygon = QPolygonF(pts)
        path = QPainterPath()
        path.addPolygon(polygon)
        return path, max_density
Пример #25
0
    def add_node_item(self, item):
        # type: (NodeItem) -> NodeItem
        """
        Add a :class:`.NodeItem` instance to the scene.
        """
        if item in self.__node_items:
            raise ValueError("%r is already in the scene." % item)

        if item.pos().isNull():
            if self.__node_items:
                pos = self.__node_items[-1].pos() + QPointF(150, 0)
            else:
                pos = QPointF(150, 150)

            item.setPos(pos)

        item.setFont(self.font())

        # Set signal mappings
        self.activated_mapper.setMapping(item, item)
        item.activated.connect(self.activated_mapper.map)

        self.hovered_mapper.setMapping(item, item)
        item.hovered.connect(self.hovered_mapper.map)

        self.position_change_mapper.setMapping(item, item)
        item.positionChanged.connect(self.position_change_mapper.map)

        self.addItem(item)

        self.__node_items.append(item)

        self.clearSelection()
        item.setSelected(True)

        self.node_item_added.emit(item)

        return item
Пример #26
0
    def add_annotation(self, scheme_annot):
        # type: (BaseSchemeAnnotation) -> Annotation
        """
        Create a new item for :class:`SchemeAnnotation` and add it
        to the scene. If the `scheme_annot` is already in the scene do
        nothing and just return its item.

        """
        if scheme_annot in self.__item_for_annotation:
            # Already added
            return self.__item_for_annotation[scheme_annot]

        if isinstance(scheme_annot, scheme.SchemeTextAnnotation):
            item = items.TextAnnotation()
            x, y, w, h = scheme_annot.rect  # type: ignore
            item.setPos(x, y)
            item.resize(w, h)
            item.setTextInteractionFlags(Qt.TextEditorInteraction)

            font = font_from_dict(scheme_annot.font,
                                  item.font())  # type: ignore
            item.setFont(font)
            item.setContent(scheme_annot.content, scheme_annot.content_type)
            scheme_annot.content_changed.connect(item.setContent)
        elif isinstance(scheme_annot, scheme.SchemeArrowAnnotation):
            item = items.ArrowAnnotation()
            start, end = scheme_annot.start_pos, scheme_annot.end_pos
            item.setLine(QLineF(QPointF(*start),
                                QPointF(*end)))  # type: ignore
            item.setColor(QColor(scheme_annot.color))

        scheme_annot.geometry_changed.connect(
            self.__on_scheme_annot_geometry_change)

        self.add_annotation_item(item)
        self.__item_for_annotation[scheme_annot] = item

        return item
Пример #27
0
    def __updateMessages(self):
        # type: () -> None
        """
        Update message items (position, visibility and tool tips).
        """
        items = [self.errorItem, self.warningItem, self.infoItem]

        messages = list(self.__messages.values()) + [
            UserMessage(
                self.__error or "", UserMessage.Error, message_id="_error"),
            UserMessage(
                self.__warning or "", UserMessage.Warning, message_id="_warn"),
            UserMessage(
                self.__info or "", UserMessage.Info, message_id="_info"),
        ]
        key = attrgetter("severity")
        messages = groupby(sorted(messages, key=key, reverse=True), key=key)

        for (_, message_g), item in zip(messages, items):
            message = "<br/>".join(m.contents for m in message_g if m.contents)
            item.setVisible(bool(message))
            if bool(message):
                item.anim.start(QPropertyAnimation.KeepWhenStopped)
            item.setToolTip(message or "")

        shown = [item for item in items if item.isVisible()]
        count = len(shown)
        if count:
            spacing = 3
            rects = [item.boundingRect() for item in shown]
            width = sum(rect.width() for rect in rects)
            width += spacing * max(0, count - 1)
            height = max(rect.height() for rect in rects)
            origin = self.shapeItem.boundingRect().top() - spacing - height
            origin = QPointF(-width / 2, origin)
            for item, rect in zip(shown, rects):
                item.setPos(origin)
                origin = origin + QPointF(rect.width() + spacing, 0)
 def test_pyside(self):
     img = QImage(100, 100, QImage.Format_ARGB32)
     img.fill(Qt.green)
     p = QPainter(img)
     pix = QPixmap(10, 10)
     pix.fill(Qt.red)
     frgmt = QPainter.PixmapFragment.create(
         QPointF(25, 25),
         QRectF(0, 0, 10, 10),
         5., 5.,
     )
     p.drawPixmapFragments(frgmt, 1, pix)
     p.end()
     self.assertEqual(QColor(img.pixel(10, 10)), QColor(Qt.red))
Пример #29
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
Пример #30
0
    def test_selection_line(self):
        event = Mock()
        event.button.return_value = Qt.LeftButton
        event.buttonDownPos.return_value = Point(0, 0)
        event.pos.return_value = Point(1, 1)
        event.isFinish.return_value = True

        # drag a line before data is sent
        self.widget.graph.view_box.mouseDragEvent(event)
        self.assertIsNone(self.widget.selection)

        # drag a line after data is sent
        self.send_signal(self.widget.Inputs.data, self.data)

        # set view-dependent click coordinates
        pos_down, pos_up = QPointF(2.38, 4.84), QPointF(3.58, 4.76)
        mapToParent = self.widget.graph.view_box.childGroup.mapToParent

        # On pyqtgraph < 0.11.1 mapping does not work unless the widget is shown
        # Delete when Orange stops supporting pyqtgraph < 0.11.1,
        to_and_back = self.widget.graph.view_box.childGroup.mapFromParent(
            mapToParent(pos_down))
        successful_mapping = (to_and_back - pos_down).manhattanLength() < 0.001
        if not successful_mapping:  # on pyqtgraph < 0.11.1
            mapToParent = lambda x: x

        event.buttonDownPos.return_value = mapToParent(pos_down)
        event.pos.return_value = mapToParent(pos_up)

        self.widget.graph.view_box.mouseDragEvent(event)
        line = self.widget.graph.view_box.selection_line
        self.assertFalse(line.line().isNull())

        # click on the plot resets selection
        self.assertEqual(len(self.widget.selection), 55)
        self.widget.graph.view_box.mouseClickEvent(event)
        self.assertListEqual(self.widget.selection, [])