def mouseMoveEvent(self, event): if event.buttons() & Qt.LeftButton: downPos = event.buttonDownPos(Qt.LeftButton) if not self.__tmpLine and self.__dragStartItem and \ (downPos - event.pos()).manhattanLength() > \ QApplication.instance().startDragDistance(): # Start a line drag line = QGraphicsLineItem(self) start = self.__dragStartItem.boundingRect().center() start = self.mapFromItem(self.__dragStartItem, start) line.setLine(start.x(), start.y(), event.pos().x(), event.pos().y()) pen = QPen(Qt.black, 4) pen.setCapStyle(Qt.RoundCap) line.setPen(pen) line.show() self.__tmpLine = line if self.__tmpLine: # Update the temp line line = self.__tmpLine.line() line.setP2(event.pos()) self.__tmpLine.setLine(line) QGraphicsWidget.mouseMoveEvent(self, event)
def mouseMoveEvent(self, event): if event.buttons() & Qt.LeftButton: downPos = event.buttonDownPos(Qt.LeftButton) if not self.__tmpLine and self.__dragStartItem and \ (downPos - event.pos()).manhattanLength() > \ QApplication.instance().startDragDistance(): # Start a line drag line = QGraphicsLineItem(self) start = self.__dragStartItem.boundingRect().center() start = self.mapFromItem(self.__dragStartItem, start) line.setLine(start.x(), start.y(), event.pos().x(), event.pos().y()) pen = QPen(self.palette().color(QPalette.Foreground), 4) pen.setCapStyle(Qt.RoundCap) line.setPen(pen) line.show() self.__tmpLine = line if self.__tmpLine: # Update the temp line line = self.__tmpLine.line() line.setP2(event.pos()) self.__tmpLine.setLine(line) QGraphicsWidget.mouseMoveEvent(self, event)
def make_pen(brush=Qt.black, width=1, style=Qt.SolidLine, cap_style=Qt.SquareCap, join_style=Qt.BevelJoin, cosmetic=False): pen = QPen(brush) pen.setWidth(width) pen.setStyle(style) pen.setCapStyle(cap_style) pen.setJoinStyle(join_style) pen.setCosmetic(cosmetic) return pen
class LinkLineItem(QGraphicsLineItem): """ A line connecting two Channel Anchors. """ def __init__(self, parent=None): super().__init__(parent) self.setAcceptHoverEvents(True) self.__shape = None self.__default_pen = QPen(QColor('#383838'), 4) self.__default_pen.setCapStyle(Qt.RoundCap) self.__hover_pen = QPen(QColor('#000000'), 4) self.__hover_pen.setCapStyle(Qt.RoundCap) self.setPen(self.__default_pen) self.__shadow = QGraphicsDropShadowEffect( blurRadius=10, color=QColor('#9CACB4'), offset=QPointF(0, 0) ) self.setGraphicsEffect(self.__shadow) self.prepareGeometryChange() self.__shadow.setEnabled(False) def setLine(self, *args, **kwargs): super().setLine(*args, **kwargs) # extends mouse hit area stroke_path = QPainterPathStroker() stroke_path.setCapStyle(Qt.RoundCap) stroke_path.setWidth(10) self.__shape = stroke_path.createStroke(super().shape()) def shape(self): if self.__shape is None: return super().shape() return self.__shape def hoverEnterEvent(self, event): self.prepareGeometryChange() self.__shadow.setEnabled(True) self.setPen(self.__hover_pen) self.setZValue(1.0) super().hoverEnterEvent(event) def hoverLeaveEvent(self, event): self.prepareGeometryChange() self.__shadow.setEnabled(False) self.setPen(self.__default_pen) self.setZValue(0.0) super().hoverLeaveEvent(event)
class LinkLineItem(QGraphicsLineItem): """ A line connecting two Channel Anchors. """ def __init__(self, parent=None): QGraphicsLineItem.__init__(self, parent) self.setAcceptHoverEvents(True) self.__shape = None self.__default_pen = QPen(QColor('#383838'), 4) self.__default_pen.setCapStyle(Qt.RoundCap) self.__hover_pen = QPen(QColor('#000000'), 4) self.__hover_pen.setCapStyle(Qt.RoundCap) self.setPen(self.__default_pen) self.__shadow = QGraphicsDropShadowEffect( blurRadius=10, color=QColor('#9CACB4'), offset=QPointF(0, 0) ) self.setGraphicsEffect(self.__shadow) self.prepareGeometryChange() self.__shadow.setEnabled(False) def setLine(self, *args, **kwargs): super().setLine(*args, **kwargs) # extends mouse hit area stroke_path = QPainterPathStroker() stroke_path.setCapStyle(Qt.RoundCap) stroke_path.setWidth(10) self.__shape = stroke_path.createStroke(super().shape()) def shape(self): if self.__shape is None: return QGraphicsLineItem.shape(self) return self.__shape def hoverEnterEvent(self, event): self.prepareGeometryChange() self.__shadow.setEnabled(True) self.setPen(self.__hover_pen) self.setZValue(1.0) QGraphicsLineItem.hoverEnterEvent(self, event) def hoverLeaveEvent(self, event): self.prepareGeometryChange() self.__shadow.setEnabled(False) self.setPen(self.__default_pen) self.setZValue(0.0) QGraphicsLineItem.hoverLeaveEvent(self, event)
def mouseMoveEvent(self, event): if event.buttons() & Qt.LeftButton: downPos = event.buttonDownPos(Qt.LeftButton) if not self.__tmpLine and self.__dragStartItem and \ (downPos - event.pos()).manhattanLength() > \ QApplication.instance().startDragDistance(): # Start a line drag line = LinkLineItem(self) start = self.__dragStartItem.boundingRect().center() start = self.mapFromItem(self.__dragStartItem, start) eventPos = event.pos() line.setLine(start.x(), start.y(), eventPos.x(), eventPos.y()) pen = QPen(self.palette().color(QPalette.Foreground), 4) pen.setCapStyle(Qt.RoundCap) line.setPen(pen) line.show() self.__tmpLine = line if self.__dragStartItem in self.sourceNodeWidget.channelAnchors: for anchor in self.sinkNodeWidget.channelAnchors: self.__updateAnchorState(anchor, [self.__dragStartItem]) else: for anchor in self.sourceNodeWidget.channelAnchors: self.__updateAnchorState(anchor, [self.__dragStartItem]) if self.__tmpLine: # Update the temp line line = self.__tmpLine.line() maybe_anchor = find_item_at(self.scene(), event.scenePos(), type=ChannelAnchor) # If hovering over anchor if maybe_anchor is not None and maybe_anchor.isEnabled(): target_pos = maybe_anchor.boundingRect().center() target_pos = self.mapFromItem(maybe_anchor, target_pos) line.setP2(target_pos) else: target_pos = event.pos() line.setP2(target_pos) self.__tmpLine.setLine(line) super().mouseMoveEvent(event)
def mouseMoveEvent(self, event): if event.buttons() & Qt.LeftButton: downPos = event.buttonDownPos(Qt.LeftButton) if not self.__tmpLine and self.__dragStartItem and \ (downPos - event.pos()).manhattanLength() > \ QApplication.instance().startDragDistance(): # Start a line drag line = LinkLineItem(self) start = self.__dragStartItem.boundingRect().center() start = self.mapFromItem(self.__dragStartItem, start) eventPos = event.pos() line.setLine(start.x(), start.y(), eventPos.x(), eventPos.y()) pen = QPen(self.palette().color(QPalette.Foreground), 4) pen.setCapStyle(Qt.RoundCap) line.setPen(pen) line.show() self.__tmpLine = line if self.__dragStartItem in self.sourceNodeWidget.channelAnchors: for anchor in self.sinkNodeWidget.channelAnchors: self.__updateAnchorState(anchor, [self.__dragStartItem]) else: for anchor in self.sourceNodeWidget.channelAnchors: self.__updateAnchorState(anchor, [self.__dragStartItem]) if self.__tmpLine: # Update the temp line line = self.__tmpLine.line() maybe_anchor = find_item_at(self.scene(), event.scenePos(), type=ChannelAnchor) # If hovering over anchor if maybe_anchor is not None and maybe_anchor.isEnabled(): target_pos = maybe_anchor.boundingRect().center() target_pos = self.mapFromItem(maybe_anchor, target_pos) line.setP2(target_pos) else: target_pos = event.pos() line.setP2(target_pos) self.__tmpLine.setLine(line) QGraphicsWidget.mouseMoveEvent(self, event)
def update_pen(pen, brush=None, width=None, style=None, cap_style=None, join_style=None, cosmetic=None): pen = QPen(pen) if brush is not None: pen.setBrush(QBrush(brush)) if width is not None: pen.setWidth(width) if style is not None: pen.setStyle(style) if cap_style is not None: pen.setCapStyle(cap_style) if join_style is not None: pen.setJoinStyle(join_style) if cosmetic is not None: pen.setCosmetic(cosmetic) return pen
def addLink(self, output, input): """ Add a link between `output` (:class:`OutputSignal`) and `input` (:class:`InputSignal`). """ if not compatible_channels(output, input): return if output not in self.source.output_channels(): raise ValueError("%r is not an output channel of %r" % \ (output, self.source)) if input not in self.sink.input_channels(): raise ValueError("%r is not an input channel of %r" % \ (input, self.sink)) if input.single: # Remove existing link if it exists. for s1, s2, _ in self.__links: if s2 == input: self.removeLink(s1, s2) line = QGraphicsLineItem(self) source_anchor = self.sourceNodeWidget.anchor(output) sink_anchor = self.sinkNodeWidget.anchor(input) source_pos = source_anchor.boundingRect().center() source_pos = self.mapFromItem(source_anchor, source_pos) sink_pos = sink_anchor.boundingRect().center() sink_pos = self.mapFromItem(sink_anchor, sink_pos) line.setLine(source_pos.x(), source_pos.y(), sink_pos.x(), sink_pos.y()) pen = QPen(self.palette().color(QPalette.Foreground), 4) pen.setCapStyle(Qt.RoundCap) line.setPen(pen) self.__links.append(_Link(output, input, line))
def addLink(self, output, input): """ Add a link between `output` (:class:`OutputSignal`) and `input` (:class:`InputSignal`). """ if not compatible_channels(output, input): return if output not in self.source.output_channels(): raise ValueError("%r is not an output channel of %r" % \ (output, self.source)) if input not in self.sink.input_channels(): raise ValueError("%r is not an input channel of %r" % \ (input, self.sink)) if input.single: # Remove existing link if it exists. for s1, s2, _ in self.__links: if s2 == input: self.removeLink(s1, s2) line = QGraphicsLineItem(self) source_anchor = self.sourceNodeWidget.anchor(output) sink_anchor = self.sinkNodeWidget.anchor(input) source_pos = source_anchor.boundingRect().center() source_pos = self.mapFromItem(source_anchor, source_pos) sink_pos = sink_anchor.boundingRect().center() sink_pos = self.mapFromItem(sink_anchor, sink_pos) line.setLine(source_pos.x(), source_pos.y(), sink_pos.x(), sink_pos.y()) pen = QPen(Qt.black, 4) pen.setCapStyle(Qt.RoundCap) line.setPen(pen) self.__links.append(_Link(output, input, line))
def replot_experiments(self): """Replot the whole quality plot. """ self.scene.clear() labels = [] max_dist = numpy.nanmax(list(filter(None, self.distances))) rug_widgets = [] group_pen = QPen(Qt.black) group_pen.setWidth(2) group_pen.setCapStyle(Qt.RoundCap) background_pen = QPen(QColor(0, 0, 250, 150)) background_pen.setWidth(1) background_pen.setCapStyle(Qt.RoundCap) main_widget = QGraphicsWidget() layout = QGraphicsGridLayout() attributes = self.data.domain.attributes if self.data is not None: for (group, indices), dist_vec in zip(self.groups, self.distances): indices_set = set(indices) rug_items = [] if dist_vec is not None: for i, attr in enumerate(attributes): # Is this a within group distance or background in_group = i in indices_set if in_group: rug_item = ClickableRugItem(dist_vec[i] / max_dist, 1.0, self.on_rug_item_clicked) rug_item.setPen(group_pen) tooltip = experiment_description(attr) rug_item.setToolTip(tooltip) rug_item.group_index = indices.index(i) rug_item.setZValue(rug_item.zValue() + 1) else: rug_item = ClickableRugItem(dist_vec[i] / max_dist, 0.85, self.on_rug_item_clicked) rug_item.setPen(background_pen) tooltip = experiment_description(attr) rug_item.setToolTip(tooltip) rug_item.group = group rug_item.index = i rug_item.in_group = in_group rug_items.append(rug_item) rug_widget = RugGraphicsWidget(parent=main_widget) rug_widget.set_rug(rug_items) rug_widgets.append(rug_widget) label = group_label(self.selected_split_by_labels(), group) label_item = QGraphicsSimpleTextItem(label, main_widget) label_item = GraphicsSimpleTextLayoutItem(label_item, parent=layout) label_item.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) labels.append(label_item) for i, (label, rug_w) in enumerate(zip(labels, rug_widgets)): layout.addItem(label, i, 0, Qt.AlignVCenter) layout.addItem(rug_w, i, 1) layout.setRowMaximumHeight(i, 30) main_widget.setLayout(layout) self.scene.addItem(main_widget) self.main_widget = main_widget self.rug_widgets = rug_widgets self.labels = labels self.on_view_resize(self.scene_view.size())