Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 from __future__ import print_function
00032
00033 import sys
00034
00035 from python_qt_binding.QtCore import Qt
00036 from python_qt_binding.QtGui import QBrush, QGraphicsEllipseItem, QGraphicsRectItem, QGraphicsSimpleTextItem, QPainterPath, QPen
00037
00038 from .dot_shapes import QGraphicsBox3dItem
00039 from .graph_item import GraphItem
00040
00041
00042 class NodeItem(GraphItem):
00043
00044 def __init__(self, highlight_level, bounding_box, label, shape, color=None, parent=None, label_pos=None, tooltip=None):
00045 super(NodeItem, self).__init__(highlight_level, parent)
00046
00047 self._default_color = self._COLOR_BLACK if color is None else color
00048 self._brush = QBrush(self._default_color)
00049 self._label_pen = QPen()
00050 self._label_pen.setColor(self._default_color)
00051 self._label_pen.setJoinStyle(Qt.RoundJoin)
00052 self._ellipse_pen = QPen(self._label_pen)
00053 self._ellipse_pen.setWidth(1)
00054
00055 self._incoming_edges = set()
00056 self._outgoing_edges = set()
00057
00058 self.parse_shape(shape, bounding_box)
00059 self.addToGroup(self._graphics_item)
00060
00061 self._label = QGraphicsSimpleTextItem(label)
00062 self._label.setFont(GraphItem._LABEL_FONT)
00063 label_rect = self._label.boundingRect()
00064 if label_pos is None:
00065 label_rect.moveCenter(bounding_box.center())
00066 else:
00067 label_rect.moveCenter(label_pos)
00068 self._label.setPos(label_rect.x(), label_rect.y())
00069 self.addToGroup(self._label)
00070 if tooltip is not None:
00071 self.setToolTip(tooltip)
00072
00073 self.set_node_color()
00074
00075 self.setAcceptHoverEvents(True)
00076
00077 self.hovershape = None
00078
00079 def parse_shape(self, shape, bounding_box):
00080 if shape in ('box', 'rect', 'rectangle'):
00081 self._graphics_item = QGraphicsRectItem(bounding_box)
00082 elif shape in ('ellipse', 'oval', 'circle'):
00083 self._graphics_item = QGraphicsEllipseItem(bounding_box)
00084 elif shape in ('box3d', ):
00085 self._graphics_item = QGraphicsBox3dItem(bounding_box)
00086 else:
00087 print("Invalid shape '%s', defaulting to ellipse" % shape, file=sys.stderr)
00088 self._graphics_item = QGraphicsEllipseItem(bounding_box)
00089
00090 def set_hovershape(self, newhovershape):
00091 self.hovershape = newhovershape
00092
00093 def shape(self):
00094 if self.hovershape is not None:
00095 path = QPainterPath()
00096 path.addRect(self.hovershape)
00097 return path
00098 else:
00099 return super(self.__class__, self).shape()
00100
00101 def add_incoming_edge(self, edge):
00102 self._incoming_edges.add(edge)
00103
00104 def add_outgoing_edge(self, edge):
00105 self._outgoing_edges.add(edge)
00106
00107 def set_node_color(self, color=None):
00108 if color is None:
00109 color = self._default_color
00110
00111 self._brush.setColor(color)
00112 self._ellipse_pen.setColor(color)
00113 self._label_pen.setColor(color)
00114
00115 self._graphics_item.setPen(self._ellipse_pen)
00116 self._label.setBrush(self._brush)
00117 self._label.setPen(self._label_pen)
00118
00119 def hoverEnterEvent(self, event):
00120
00121 self.set_node_color(self._COLOR_RED)
00122
00123 if self._highlight_level > 1:
00124 cyclic_edges = self._incoming_edges.intersection(self._outgoing_edges)
00125
00126 incoming_nodes = set()
00127 for incoming_edge in self._incoming_edges.difference(cyclic_edges):
00128 incoming_edge.set_node_color(self._COLOR_BLUE)
00129 if incoming_edge.from_node != self:
00130 incoming_nodes.add(incoming_edge.from_node)
00131
00132 outgoing_nodes = set()
00133 for outgoing_edge in self._outgoing_edges.difference(cyclic_edges):
00134 outgoing_edge.set_node_color(self._COLOR_GREEN)
00135 if outgoing_edge.to_node != self:
00136 outgoing_nodes.add(outgoing_edge.to_node)
00137
00138 for edge in cyclic_edges:
00139 edge.set_node_color(self._COLOR_TEAL)
00140
00141 if self._highlight_level > 2:
00142 cyclic_nodes = incoming_nodes.intersection(outgoing_nodes)
00143
00144 for incoming_node in incoming_nodes.difference(cyclic_nodes):
00145 incoming_node.set_node_color(self._COLOR_BLUE)
00146
00147 for outgoing_node in outgoing_nodes.difference(cyclic_nodes):
00148 outgoing_node.set_node_color(self._COLOR_GREEN)
00149
00150 for node in cyclic_nodes:
00151 node.set_node_color(self._COLOR_TEAL)
00152
00153 def hoverLeaveEvent(self, event):
00154 self.set_node_color()
00155 if self._highlight_level > 1:
00156 for incoming_edge in self._incoming_edges:
00157 incoming_edge.set_node_color()
00158 if self._highlight_level > 2 and incoming_edge.from_node != self:
00159 incoming_edge.from_node.set_node_color()
00160 for outgoing_edge in self._outgoing_edges:
00161 outgoing_edge.set_node_color()
00162 if self._highlight_level > 2 and outgoing_edge.to_node != self:
00163 outgoing_edge.to_node.set_node_color()