node_item.py
Go to the documentation of this file.
1 # Copyright (c) 2011, Dirk Thomas, TU Darmstadt
2 # All rights reserved.
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions
6 # are met:
7 #
8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above
11 # copyright notice, this list of conditions and the following
12 # disclaimer in the documentation and/or other materials provided
13 # with the distribution.
14 # * Neither the name of the TU Darmstadt nor the names of its
15 # contributors may be used to endorse or promote products derived
16 # from this software without specific prior written permission.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 # POSSIBILITY OF SUCH DAMAGE.
30 
31 from __future__ import print_function
32 
33 import sys
34 
35 from python_qt_binding.QtCore import Qt
36 from python_qt_binding.QtGui import QBrush, QPainterPath, QPen
37 from python_qt_binding.QtWidgets import (QGraphicsEllipseItem,
38  QGraphicsRectItem,
39  QGraphicsSimpleTextItem)
40 
41 from qt_dotgraph.dot_shapes import QGraphicsBox3dItem
42 from qt_dotgraph.graph_item import GraphItem
43 
44 
46 
47  def __init__(
48  self, highlight_level, bounding_box, label, shape, color=None,
49  parent=None, label_pos=None, tooltip=None):
50  super(NodeItem, self).__init__(highlight_level, parent)
51 
52  self._default_color = self._COLOR_BLACK if color is None else color
53  self._brush = QBrush(self._default_color)
54  self._label_pen = QPen()
55  self._label_pen.setColor(self._default_color)
56  self._label_pen.setJoinStyle(Qt.RoundJoin)
57  self._ellipse_pen = QPen(self._label_pen)
58  self._ellipse_pen.setWidth(1)
59 
60  self._incoming_edges = set()
61  self._outgoing_edges = set()
62 
63  self.parse_shape(shape, bounding_box)
64  self.addToGroup(self._graphics_item)
65 
66  self._label = QGraphicsSimpleTextItem(label)
67  self._label.setFont(GraphItem._LABEL_FONT)
68  label_rect = self._label.boundingRect()
69  if label_pos is None:
70  label_rect.moveCenter(bounding_box.center())
71  else:
72  label_rect.moveCenter(label_pos)
73  self._label.setPos(label_rect.x(), label_rect.y())
74  self.addToGroup(self._label)
75  if tooltip is not None:
76  self.setToolTip(tooltip)
77 
78  self.set_node_color()
79 
80  self.setAcceptHoverEvents(True)
81 
82  self.hovershape = None
83 
84  def parse_shape(self, shape, bounding_box):
85  if shape in ('box', 'rect', 'rectangle'):
86  self._graphics_item = QGraphicsRectItem(bounding_box)
87  elif shape in ('ellipse', 'oval', 'circle'):
88  self._graphics_item = QGraphicsEllipseItem(bounding_box)
89  elif shape in ('box3d', ):
90  self._graphics_item = QGraphicsBox3dItem(bounding_box)
91  else:
92  print("Invalid shape '%s', defaulting to ellipse" % shape, file=sys.stderr)
93  self._graphics_item = QGraphicsEllipseItem(bounding_box)
94 
95  def set_hovershape(self, newhovershape):
96  self.hovershape = newhovershape
97 
98  def shape(self):
99  if self.hovershape is not None:
100  path = QPainterPath()
101  path.addRect(self.hovershape)
102  return path
103  else:
104  return super(self.__class__, self).shape()
105 
106  def add_incoming_edge(self, edge):
107  self._incoming_edges.add(edge)
108 
109  def add_outgoing_edge(self, edge):
110  self._outgoing_edges.add(edge)
111 
112  def set_node_color(self, color=None):
113  if color is None:
114  color = self._default_color
115 
116  self._brush.setColor(color)
117  self._ellipse_pen.setColor(color)
118  self._label_pen.setColor(color)
119 
120  self._graphics_item.setPen(self._ellipse_pen)
121  self._label.setBrush(self._brush)
122  self._label.setPen(self._label_pen)
123 
124  def hoverEnterEvent(self, event):
125  # hovered node item in red
126  self.set_node_color(self._COLOR_RED)
127 
128  if self._highlight_level > 1:
129  cyclic_edges = self._incoming_edges.intersection(self._outgoing_edges)
130  # incoming edges in blue
131  incoming_nodes = set()
132  for incoming_edge in self._incoming_edges.difference(cyclic_edges):
133  incoming_edge.set_node_color(self._COLOR_BLUE)
134  incoming_edge.set_label_color(self._COLOR_BLUE)
135  if incoming_edge.from_node != self:
136  incoming_nodes.add(incoming_edge.from_node)
137  # outgoing edges in green
138  outgoing_nodes = set()
139  for outgoing_edge in self._outgoing_edges.difference(cyclic_edges):
140  outgoing_edge.set_node_color(self._COLOR_GREEN)
141  outgoing_edge.set_label_color(self._COLOR_GREEN)
142  if outgoing_edge.to_node != self:
143  outgoing_nodes.add(outgoing_edge.to_node)
144  # incoming/outgoing edges in teal
145  for edge in cyclic_edges:
146  edge.set_node_color(self._COLOR_TEAL)
147 
148  if self._highlight_level > 2:
149  cyclic_nodes = incoming_nodes.intersection(outgoing_nodes)
150  # incoming nodes in blue
151  for incoming_node in incoming_nodes.difference(cyclic_nodes):
152  incoming_node.set_node_color(self._COLOR_BLUE)
153  # outgoing nodes in green
154  for outgoing_node in outgoing_nodes.difference(cyclic_nodes):
155  outgoing_node.set_node_color(self._COLOR_GREEN)
156  # incoming/outgoing nodes in teal
157  for node in cyclic_nodes:
158  node.set_node_color(self._COLOR_TEAL)
159 
160  def hoverLeaveEvent(self, event):
161  self.set_node_color()
162  if self._highlight_level > 1:
163  for incoming_edge in self._incoming_edges:
164  incoming_edge.set_node_color()
165  incoming_edge.set_label_color()
166  if self._highlight_level > 2 and incoming_edge.from_node != self:
167  incoming_edge.from_node.set_node_color()
168  for outgoing_edge in self._outgoing_edges:
169  outgoing_edge.set_node_color()
170  outgoing_edge.set_label_color()
171  if self._highlight_level > 2 and outgoing_edge.to_node != self:
172  outgoing_edge.to_node.set_node_color()
def add_outgoing_edge(self, edge)
Definition: node_item.py:109
def __init__(self, highlight_level, bounding_box, label, shape, color=None, parent=None, label_pos=None, tooltip=None)
Definition: node_item.py:49
def set_node_color(self, color=None)
Definition: node_item.py:112
def hoverLeaveEvent(self, event)
Definition: node_item.py:160
def set_hovershape(self, newhovershape)
Definition: node_item.py:95
def parse_shape(self, shape, bounding_box)
Definition: node_item.py:84
def add_incoming_edge(self, edge)
Definition: node_item.py:106
def hoverEnterEvent(self, event)
Definition: node_item.py:124


qt_dotgraph
Author(s): Thibault Kruse, Dirk Thomas
autogenerated on Fri Jun 24 2022 02:42:36