def paint(self, painter, option, widget): """ Draws the node base not the ports. Args: painter (QtGui.QPainter): painter used for drawing the item. option (QtGui.QStyleOptionGraphicsItem): used to describe the parameters needed to draw. widget (QtWidgets.QWidget): not used. """ painter.save() bg_border = 1.0 rect = QtCore.QRectF(0.5 - (bg_border / 2), 0.5 - (bg_border / 2), self._width + bg_border, self._height + bg_border) radius = 2 border_color = QtGui.QColor(*self.border_color) path = QtGui.QPainterPath() path.addRoundedRect(rect, radius, radius) rect = self.boundingRect() bg_color = QtGui.QColor(*self.color) painter.setBrush(bg_color) painter.setPen(QtCore.Qt.NoPen) painter.drawRoundedRect(rect, radius, radius) if self.selected and NODE_SEL_COLOR: painter.setBrush(QtGui.QColor(*NODE_SEL_COLOR)) painter.drawRoundedRect(rect, radius, radius) label_rect = QtCore.QRectF(rect.left() + (radius / 2), rect.top() + (radius / 2), self._width - (radius / 1.25), 28) path = QtGui.QPainterPath() path.addRoundedRect(label_rect, radius / 1.5, radius / 1.5) painter.setBrush(QtGui.QColor(0, 0, 0, 50)) painter.fillPath(path, painter.brush()) border_width = 0.8 if self.selected and NODE_SEL_BORDER_COLOR: border_width = 1.2 border_color = QtGui.QColor(*NODE_SEL_BORDER_COLOR) border_rect = QtCore.QRectF(rect.left() - (border_width / 2), rect.top() - (border_width / 2), rect.width() + border_width, rect.height() + border_width) pen = QtGui.QPen(border_color, border_width) pen.setCosmetic(self.viewer().get_zoom() < 0.0) path = QtGui.QPainterPath() path.addRoundedRect(border_rect, radius, radius) painter.setBrush(QtCore.Qt.NoBrush) painter.setPen(pen) painter.drawPath(path) painter.restore()
def paint(self, painter, option, widget): """ Draws the backdrop rect. Args: painter (QtGui.QPainter): painter used for drawing the item. option (QtGui.QStyleOptionGraphicsItem): used to describe the parameters needed to draw. widget (QtWidgets.QWidget): not used. """ painter.save() rect = self.boundingRect() color = (self.color[0], self.color[1], self.color[2], 50) painter.setBrush(QtGui.QColor(*color)) painter.setPen(QtCore.Qt.NoPen) painter.drawRect(rect) top_rect = QtCore.QRectF(0.0, 0.0, rect.width(), 20.0) painter.setBrush(QtGui.QColor(*self.color)) painter.setPen(QtCore.Qt.NoPen) painter.drawRect(top_rect) if self.backdrop_text: painter.setPen(QtGui.QColor(*self.text_color)) txt_rect = QtCore.QRectF(top_rect.x() + 5.0, top_rect.height() + 2.0, rect.width() - 5.0, rect.height()) painter.setPen(QtGui.QColor(*self.text_color)) painter.drawText(txt_rect, QtCore.Qt.AlignLeft | QtCore.Qt.TextWordWrap, self.backdrop_text) if self.selected and NODE_SEL_COLOR: sel_color = [x for x in NODE_SEL_COLOR] sel_color[-1] = 10 painter.setBrush(QtGui.QColor(*sel_color)) painter.setPen(QtCore.Qt.NoPen) painter.drawRect(rect) txt_rect = QtCore.QRectF(top_rect.x(), top_rect.y() + 1.2, rect.width(), top_rect.height()) painter.setPen(QtGui.QColor(*self.text_color)) painter.drawText(txt_rect, QtCore.Qt.AlignCenter, self.name) path = QtGui.QPainterPath() path.addRect(rect) border_color = self.color if self.selected and NODE_SEL_BORDER_COLOR: border_color = NODE_SEL_BORDER_COLOR painter.setBrush(QtCore.Qt.NoBrush) painter.setPen(QtGui.QPen(QtGui.QColor(*border_color), 1)) painter.drawPath(path) painter.restore()
def mousePressEvent(self, event): alt_modifier = event.modifiers() == QtCore.Qt.AltModifier shift_modifier = event.modifiers() == QtCore.Qt.ShiftModifier if event.button() == QtCore.Qt.LeftButton: self.LMB_state = True elif event.button() == QtCore.Qt.RightButton: self.RMB_state = True elif event.button() == QtCore.Qt.MiddleButton: self.MMB_state = True self._origin_pos = event.pos() self._previous_pos = event.pos() self._prev_selection = self.selected_nodes() # close tab search if self._search_widget.isVisible(): self.tab_search_toggle() # cursor pos. map_pos = self.mapToScene(event.pos()) # pipe slicer enabled. if event.modifiers() == (QtCore.Qt.AltModifier | QtCore.Qt.ShiftModifier): self._pipe_slicer.draw_path(map_pos, map_pos) self._pipe_slicer.setVisible(True) return if alt_modifier: return items = self._items_near(map_pos, None, 20, 20) nodes = [i for i in items if isinstance(i, AbstractNodeItem)] # toggle extend node selection. if shift_modifier: for node in nodes: node.selected = not node.selected # update the recorded node positions. self._node_positions.update( {n: n.xy_pos for n in self.selected_nodes()}) # show selection selection marquee if self.LMB_state and not items: rect = QtCore.QRect(self._previous_pos, QtCore.QSize()) rect = rect.normalized() map_rect = self.mapToScene(rect).boundingRect() self.scene().update(map_rect) self._rubber_band.setGeometry(rect) self._rubber_band.show() if not shift_modifier: super(NodeViewer, self).mousePressEvent(event)
def paint(self, painter, option, widget): """ Draws the circular port. Args: painter (QtGui.QPainter): painter used for drawing the item. option (QtGui.QStyleOptionGraphicsItem): used to describe the parameters needed to draw. widget (QtWidgets.QWidget): not used. """ painter.save() rect = QtCore.QRectF(0.0, 0.8, self._width, self._height) path = QtGui.QPainterPath() path.addEllipse(rect) if self._hovered: color = QtGui.QColor(*PORT_HOVER_COLOR) border_color = QtGui.QColor(*PORT_HOVER_BORDER_COLOR) elif self.connected_pipes: color = QtGui.QColor(*PORT_ACTIVE_COLOR) border_color = QtGui.QColor(*PORT_ACTIVE_BORDER_COLOR) else: color = QtGui.QColor(*self.color) border_color = QtGui.QColor(*self.border_color) painter.setBrush(color) pen = QtGui.QPen(border_color, 1.5) painter.setPen(pen) painter.drawEllipse(self.boundingRect()) if self.connected_pipes and not self._hovered: painter.setBrush(border_color) w = self._width / 2.5 h = self._height / 2.5 rect = QtCore.QRectF(self.boundingRect().center().x() - w / 2, self.boundingRect().center().y() - h / 2, w, h) painter.drawEllipse(rect) elif self._hovered: if self.multi_connection: painter.setBrush(color) w = self._width / 1.8 h = self._height / 1.8 else: painter.setBrush(border_color) w = self._width / 3.5 h = self._height / 3.5 rect = QtCore.QRectF(self.boundingRect().center().x() - w / 2, self.boundingRect().center().y() - h / 2, w, h) painter.drawEllipse(rect) painter.restore()
def draw_path(self, start_port, end_port, cursor_pos=None): """ Draws the path between ports. Args: start_port (PortItem): port used to draw the starting point. end_port (PortItem): port used to draw the end point. cursor_pos (QtCore.QPointF): cursor position if specified this will be the draw end point. """ if not start_port: return offset = (start_port.boundingRect().width() / 2) pos1 = start_port.scenePos() pos1.setX(pos1.x() + offset) pos1.setY(pos1.y() + offset) if cursor_pos: pos2 = cursor_pos elif end_port: offset = start_port.boundingRect().width() / 2 pos2 = end_port.scenePos() pos2.setX(pos2.x() + offset) pos2.setY(pos2.y() + offset) else: return line = QtCore.QLineF(pos1, pos2) path = QtGui.QPainterPath() path.moveTo(line.x1(), line.y1()) if self.viewer_pipe_layout() == PIPE_LAYOUT_STRAIGHT: path.lineTo(pos2) self.setPath(path) return ctr_offset_x1, ctr_offset_x2 = pos1.x(), pos2.x() tangent = ctr_offset_x1 - ctr_offset_x2 tangent = (tangent * -1) if tangent < 0 else tangent max_width = start_port.node.boundingRect().width() / 2 tangent = max_width if tangent > max_width else tangent if start_port.port_type == IN_PORT: ctr_offset_x1 -= tangent ctr_offset_x2 += tangent else: ctr_offset_x1 += tangent ctr_offset_x2 -= tangent ctr_point1 = QtCore.QPointF(ctr_offset_x1, pos1.y()) ctr_point2 = QtCore.QPointF(ctr_offset_x2, pos2.y()) path.cubicTo(ctr_point1, ctr_point2, pos2) self.setPath(path)
class _valueMenu(QtWidgets.QMenu): mouseMove = QtCore.Signal(object) mouseRelease = QtCore.Signal(object) stepChange = QtCore.Signal() def __init__(self, parent=None): super(_valueMenu, self).__init__(parent) self.step = 1 self.last_action = None self.steps = [] def set_steps(self, steps): self.clear() self.steps = steps for step in steps: self._add_action(step) def _add_action(self, step): action = QtWidgets.QAction(str(step), self) action.step = step self.addAction(action) def mouseMoveEvent(self, event): self.mouseMove.emit(event) super(_valueMenu, self).mouseMoveEvent(event) action = self.actionAt(event.pos()) if action: if action is not self.last_action: self.stepChange.emit() self.last_action = action self.step = action.step elif self.last_action: self.setActiveAction(self.last_action) def mousePressEvent(self, event): return def mouseReleaseEvent(self, event): self.mouseRelease.emit(event) super(_valueMenu, self).mouseReleaseEvent(event) def set_data_type(self, dt): if dt is int: new_steps = [] for step in self.steps: if "." not in str(step): new_steps.append(step) self.set_steps(new_steps) elif dt is float: self.set_steps(self.steps)
def draw_triangle_port(painter, rect, info): """ Custom paint function for drawing a Triangle shaped port. Args: painter (QtGui.QPainter): painter object. rect (QtCore.QRectF): port rect used to describe parameters needed to draw. info (dict): information describing the ports current state. { 'port_type': 'in', 'color': (0, 0, 0), 'border_color': (255, 255, 255), 'multi_connection': False, 'connected': False, 'hovered': False, } """ painter.save() size = int(rect.height() / 2) triangle = QtGui.QPolygonF() triangle.append(QtCore.QPointF(-size, size)) triangle.append(QtCore.QPointF(0.0, -size)) triangle.append(QtCore.QPointF(size, size)) transform = QtGui.QTransform() transform.translate(rect.center().x(), rect.center().y()) port_poly = transform.map(triangle) # mouse over port color. if info['hovered']: color = QtGui.QColor(14, 45, 59) border_color = QtGui.QColor(136, 255, 35) # port connected color. elif info['connected']: color = QtGui.QColor(195, 60, 60) border_color = QtGui.QColor(200, 130, 70) # default port color else: color = QtGui.QColor(*info['color']) border_color = QtGui.QColor(*info['border_color']) pen = QtGui.QPen(border_color, 1.8) pen.setJoinStyle(QtCore.Qt.MiterJoin) painter.setPen(pen) painter.setBrush(color) painter.drawPolygon(port_poly) painter.restore()
def _draw_grid(self, painter, rect, pen, grid_size): lines = [] left = int(rect.left()) - (int(rect.left()) % grid_size) top = int(rect.top()) - (int(rect.top()) % grid_size) x = left while x < rect.right(): x += grid_size lines.append(QtCore.QLineF(x, rect.top(), x, rect.bottom())) y = top while y < rect.bottom(): y += grid_size lines.append(QtCore.QLineF(rect.left(), y, rect.right(), y)) painter.setPen(pen) painter.drawLines(lines)
def __init__(self, input_port=None, output_port=None): super(Pipe, self).__init__() self.setZValue(Z_VAL_PIPE) self.setAcceptHoverEvents(True) self._color = PIPE_DEFAULT_COLOR self._style = PIPE_STYLE_DEFAULT self._active = False self._highlight = False self._input_port = input_port self._output_port = output_port size = 6.0 self._arrow = QtGui.QPolygonF() self._arrow.append(QtCore.QPointF(-size, size)) self._arrow.append(QtCore.QPointF(0.0, -size * 1.5)) self._arrow.append(QtCore.QPointF(size, size))
class PropLineEdit(QtWidgets.QLineEdit): value_changed = QtCore.Signal(str, object) def __init__(self, parent=None): super(PropLineEdit, self).__init__(parent) self.__prev_text = '' self.returnPressed.connect(self._on_return_pressed) def focusInEvent(self, event): super(PropLineEdit, self).focusInEvent(event) self.__prev_text = self.text() def focusOutEvent(self, event): super(PropLineEdit, self).focusOutEvent(event) if self.__prev_text != self.text(): self.value_changed.emit(self.toolTip(), self.text()) self.__prev_text = '' def _on_return_pressed(self): if self.__prev_text != self.text(): self.value_changed.emit(self.toolTip(), self.text()) def get_value(self): return self.text() def set_value(self, value): if value != self.get_value(): self.setText(str(value)) self.value_changed.emit(self.toolTip(), value)
class PropTextEdit(QtWidgets.QTextEdit): value_changed = QtCore.Signal(str, object) def __init__(self, parent=None): super(PropTextEdit, self).__init__(parent) self.__prev_text = '' def focusInEvent(self, event): super(PropTextEdit, self).focusInEvent(event) self.__prev_text = self.toPlainText() def focusOutEvent(self, event): super(PropTextEdit, self).focusOutEvent(event) if self.__prev_text != self.toPlainText(): self.value_changed.emit(self.toolTip(), self.toPlainText()) self.__prev_text = '' def get_value(self): return self.toPlainText() def set_value(self, value): _value = str(value) if _value != self.get_value(): self.setPlainText(_value) self.value_changed.emit(self.toolTip(), _value)
def mouseReleaseEvent(self, event): if event.button() == QtCore.Qt.LeftButton: self.LMB_state = False elif event.button() == QtCore.Qt.RightButton: self.RMB_state = False elif event.button() == QtCore.Qt.MiddleButton: self.MMB_state = False # hide pipe slicer. if self._pipe_slicer.isVisible(): self._on_pipes_sliced(self._pipe_slicer.path()) p = QtCore.QPointF(0.0, 0.0) self._pipe_slicer.draw_path(p, p) self._pipe_slicer.setVisible(False) # hide selection marquee if self._rubber_band.isVisible(): rect = self._rubber_band.rect() map_rect = self.mapToScene(rect).boundingRect() self._rubber_band.hide() self.scene().update(map_rect) # find position changed nodes and emit signal. moved_nodes = { n: xy_pos for n, xy_pos in self._node_positions.items() if n.xy_pos != xy_pos } if moved_nodes: self.moved_nodes.emit(moved_nodes) # reset recorded positions. self._node_positions = {} super(NodeViewer, self).mouseReleaseEvent(event)
def paintEvent(self, event): size = self.geometry() rect = QtCore.QRect(1, 1, size.width() - 2, size.height() - 2) painter = QtGui.QPainter(self) painter.setPen(QtCore.Qt.NoPen) painter.setBrush(QtGui.QColor(*self._color)) painter.drawRoundedRect(rect, 1, 1)
def paint(self, painter, option, widget): """ Draws the circular port. Args: painter (QtGui.QPainter): painter used for drawing the item. option (QtGui.QStyleOptionGraphicsItem): used to describe the parameters needed to draw. widget (QtWidgets.QWidget): not used. """ painter.save() rect = QtCore.QRectF(0.0, 0.8, self._width, self._height) painter.setBrush(QtGui.QColor(0, 0, 0, 200)) painter.setPen(QtGui.QPen(QtGui.QColor(0, 0, 0, 255), 1.8)) path = QtGui.QPainterPath() path.addEllipse(rect) painter.drawPath(path) if self._hovered: color = QtGui.QColor(*PORT_HOVER_COLOR) border_color = QtGui.QColor(*PORT_HOVER_BORDER_COLOR) elif self.connected_pipes: color = QtGui.QColor(*PORT_ACTIVE_COLOR) border_color = QtGui.QColor(*PORT_ACTIVE_BORDER_COLOR) else: color = QtGui.QColor(*self.color) border_color = QtGui.QColor(*self.border_color) painter.setBrush(color) pen = QtGui.QPen(border_color, 1.5) painter.setPen(pen) painter.drawEllipse(self.boundingRect()) painter.restore()
def paint(self, painter, option, index): """ Args: painter (QtGui.QPainter): option (QtGui.QStyleOptionViewItem): index (QtCore.QModelIndex): """ painter.save() painter.setRenderHint(QtGui.QPainter.Antialiasing, False) painter.setPen(QtCore.Qt.NoPen) painter.setBrush(option.palette.midlight()) painter.drawRect(option.rect) if option.state & QtWidgets.QStyle.State_Selected: bdr_clr = option.palette.highlight().color() painter.setPen(QtGui.QPen(bdr_clr, 1.5)) else: bdr_clr = option.palette.alternateBase().color() painter.setPen(QtGui.QPen(bdr_clr, 1)) painter.setBrush(QtCore.Qt.NoBrush) painter.drawRect(QtCore.QRect(option.rect.x() + 1, option.rect.y() + 1, option.rect.width() - 2, option.rect.height() - 2)) painter.restore()
def mouseMoveEvent(self, event): alt_modifier = event.modifiers() == QtCore.Qt.AltModifier shift_modifier = event.modifiers() == QtCore.Qt.ShiftModifier if self.MMB_state and alt_modifier: pos_x = (event.x() - self._previous_pos.x()) zoom = 0.1 if pos_x > 0 else -0.1 self._set_viewer_zoom(zoom) elif self.MMB_state or (self.LMB_state and alt_modifier): pos_x = (event.x() - self._previous_pos.x()) pos_y = (event.y() - self._previous_pos.y()) self._set_viewer_pan(pos_x, pos_y) if self.LMB_state and self._rubber_band.isVisible(): rect = QtCore.QRect(self._origin_pos, event.pos()).normalized() map_rect = self.mapToScene(rect).boundingRect() path = QtGui.QPainterPath() path.addRect(map_rect) self._rubber_band.setGeometry(rect) self.scene().setSelectionArea(path, QtCore.Qt.IntersectsItemShape) self.scene().update(map_rect) if shift_modifier and self._prev_selection: for node in self._prev_selection: if node not in self.selected_nodes(): node.selected = True self._previous_pos = event.pos() super(NodeViewer, self).mouseMoveEvent(event)
def reset_zoom(self, cent=None): self._scene_range = QtCore.QRectF(0, 0, self.size().width(), self.size().height()) if cent: self._scene_range.translate(cent - self._scene_range.center()) self._update_scene()
class PropComboBox(QtWidgets.QComboBox): value_changed = QtCore.Signal(str, object) def __init__(self, parent=None): super(PropComboBox, self).__init__(parent) self.currentIndexChanged.connect(self._on_index_changed) def _on_index_changed(self): self.value_changed.emit(self.toolTip(), self.get_value()) def items(self): return [self.itemText(i) for i in range(self.count())] def set_items(self, items): self.clear() self.addItems(items) def get_value(self): return self.currentText() def set_value(self, value): if type(value) is list: self.set_items(value) return if value != self.get_value(): idx = self.findText(value, QtCore.Qt.MatchExactly) self.setCurrentIndex(idx) if idx >= 0: self.value_changed.emit(self.toolTip(), value)
class TabSearchWidget(QtWidgets.QLineEdit): search_submitted = QtCore.Signal(str) def __init__(self, parent=None, node_dict=None): super(TabSearchWidget, self).__init__(parent) self.setAttribute(QtCore.Qt.WA_MacShowFocusRect, 0) self.setStyleSheet(STYLE_TABSEARCH) self.setMinimumSize(200, 22) self.setTextMargins(2, 0, 2, 0) self.hide() self._node_dict = node_dict or {} node_names = sorted(self._node_dict.keys()) self._model = QtCore.QStringListModel(node_names, self) self._completer = TabSearchCompleter() self._completer.setModel(self._model) self.setCompleter(self._completer) popup = self._completer.popup() popup.setStyleSheet(STYLE_TABSEARCH_LIST) popup.clicked.connect(self._on_search_submitted) self.returnPressed.connect(self._on_search_submitted) def __repr__(self): return '<{} at {}>'.format(self.__class__.__name__, hex(id(self))) def _on_search_submitted(self, index=0): node_type = self._node_dict.get(self.text()) if node_type: self.search_submitted.emit(node_type) self.close() self.parentWidget().clearFocus() def showEvent(self, event): super(TabSearchWidget, self).showEvent(event) self.setSelection(0, len(self.text())) self.setFocus() if not self.text(): self.completer().popup().show() self.completer().complete() def mousePressEvent(self, event): if not self.text(): self.completer().complete() def set_nodes(self, node_dict=None): self._node_dict = {} for name, node_types in node_dict.items(): if len(node_types) == 1: self._node_dict[name] = node_types[0] continue for node_id in node_types: self._node_dict['{} ({})'.format(name, node_id)] = node_id node_names = sorted(self._node_dict.keys()) self._model.setStringList(node_names) self._completer.setModel(self._model)
def __init__(self, input_port=None, output_port=None): super(Pipe, self).__init__() self.setZValue(Z_VAL_PIPE) self.setAcceptHoverEvents(True) self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable) self._color = PIPE_DEFAULT_COLOR self._style = PIPE_STYLE_DEFAULT self._active = False self._highlight = False self._input_port = input_port self._output_port = output_port size = 6.0 self._arrow = QtGui.QPolygonF() self._arrow.append(QtCore.QPointF(-size, size)) self._arrow.append(QtCore.QPointF(0.0, -size * 1.5)) self._arrow.append(QtCore.QPointF(size, size)) self.setCacheMode(ITEM_CACHE_MODE)
def __init__(self): super(TickTimeNode, self).__init__() self.add_output('out', float) self.add_float_input('out', 'Data Input', value=0.0) self.timer = QtCore.QTimer() self.timer.timeout.connect(self.tick) self.timer.start(1000)
def updateModel(self): if not self._using_orig_model: self._filter_model.setSourceModel(self._source_model) pattern = QtCore.QRegExp(self._local_completion_prefix, QtCore.Qt.CaseInsensitive, QtCore.QRegExp.FixedString) self._filter_model.setFilterRegExp(pattern)
def splitPath(self, path): self._local_completion_prefix = path self.updateModel() if self._filter_model.rowCount() == 0: self._using_orig_model = False self._filter_model.setSourceModel(QtCore.QStringListModel([path])) return [path] return []
def _items_near(self, pos, item_type=None, width=20, height=20): x, y = pos.x() - width, pos.y() - height rect = QtCore.QRectF(x, y, width, height) items = [] for item in self.scene().items(rect): if not item_type or isinstance(item, item_type): items.append(item) return items
class BaseProperty(QtWidgets.QWidget): value_changed = QtCore.Signal(str, object) def set_value(self, value): raise NotImplementedError def get_value(self): raise NotImplementedError
def itemChange(self, change, value): if change == self.ItemPositionChange: mx, my = self.controller.minimum_size x = mx if value.x() < mx else value.x() y = my if value.y() < my else value.y() value = QtCore.QPointF(x, y) self.controller.on_sizer_pos_changed(value) return value return super().itemChange(change, value)
def __init__(self): super(TickTimeNode, self).__init__() self.add_output('out') self.add_text_input('out', 'Ticks', text='0', tab='widgets') self.view.widgets['out'].value_changed.connect(self.update_stream) self.timer = QtCore.QTimer() self.timer.timeout.connect(self.tick) self.timer.start(1000)
def paint(self, painter, option, widget): """ Draws the slicer pipe. Args: painter (QtGui.QPainter): painter used for drawing the item. option (QtGui.QStyleOptionGraphicsItem): used to describe the parameters needed to draw. widget (QtWidgets.QWidget): not used. """ color = QtGui.QColor(*PIPE_SLICER_COLOR) p1 = self.path().pointAtPercent(0) p2 = self.path().pointAtPercent(1) size = 6.0 offset = size / 2 painter.save() painter.setRenderHint(painter.Antialiasing, True) font = painter.font() font.setPointSize(12) painter.setFont(font) text = 'slice' text_x = painter.fontMetrics().width(text) / 2 text_y = painter.fontMetrics().height() / 1.5 text_pos = QtCore.QPointF(p1.x() - text_x, p1.y() - text_y) text_color = QtGui.QColor(*PIPE_SLICER_COLOR) text_color.setAlpha(80) painter.setPen(QtGui.QPen(text_color, 1.5, QtCore.Qt.SolidLine)) painter.drawText(text_pos, text) painter.setPen(QtGui.QPen(color, 1.5, QtCore.Qt.DashLine)) painter.drawPath(self.path()) painter.setPen(QtGui.QPen(color, 1.5, QtCore.Qt.SolidLine)) painter.setBrush(color) rect = QtCore.QRectF(p1.x() - offset, p1.y() - offset, size, size) painter.drawEllipse(rect) rect = QtCore.QRectF(p2.x() - offset, p2.y() - offset, size, size) painter.drawEllipse(rect) painter.restore()
def itemChange(self, change, value): if change == self.ItemPositionChange: item = self.parentItem() mx, my = item.minimum_size x = mx if value.x() < mx else value.x() y = my if value.y() < my else value.y() value = QtCore.QPointF(x, y) item.on_sizer_pos_changed(value) return value return super(BackdropSizer, self).itemChange(change, value)
class PropLabel(QtWidgets.QLabel): value_changed = QtCore.Signal(str, object) def get_value(self): return self.text() def set_value(self, value): if value != self.get_value(): self.setText(str(value)) self.value_changed.emit(self.toolTip(), value)