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
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
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()
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
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)
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)
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))
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)
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
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()
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)
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)
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)
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)
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))
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()
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)
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, ]
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)
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)
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
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
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
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))
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
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, [])