edge_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 python_qt_binding.QtCore import QPointF, Qt
32 from python_qt_binding.QtGui import QBrush, QPainterPath, QPen, QPolygonF
33 from python_qt_binding.QtWidgets import (QGraphicsPathItem,
34  QGraphicsPolygonItem,
35  QGraphicsSimpleTextItem)
36 
37 
38 from qt_dotgraph.graph_item import GraphItem
39 
40 
42 
43  _qt_pen_styles = {
44  'dashed': Qt.DashLine,
45  'dotted': Qt.DotLine,
46  'solid': Qt.SolidLine,
47  }
48 
49  def __init__(
50  self, highlight_level, spline, label_center, label, from_node, to_node,
51  parent=None, penwidth=1, edge_color=None, style='solid'):
52  super(EdgeItem, self).__init__(highlight_level, parent)
53 
54  self.from_node = from_node
55  self.from_node.add_outgoing_edge(self)
56  self.to_node = to_node
57  self.to_node.add_incoming_edge(self)
58 
60  if edge_color is not None:
61  self._default_edge_color = edge_color
62 
65  self._text_brush = QBrush(self._default_color)
66  self._shape_brush = QBrush(self._default_color)
67  if style in ['dashed', 'dotted']:
68  self._shape_brush = QBrush(Qt.transparent)
69  self._label_pen = QPen()
70  self._label_pen.setColor(self._default_text_color)
71  self._label_pen.setJoinStyle(Qt.RoundJoin)
72  self._edge_pen = QPen(self._label_pen)
73  self._edge_pen.setWidth(penwidth)
74  self._edge_pen.setColor(self._default_edge_color)
75  self._edge_pen.setStyle(self._qt_pen_styles.get(style, Qt.SolidLine))
76 
77  self._sibling_edges = set()
78 
79  self._label = None
80  if label is not None:
81  self._label = QGraphicsSimpleTextItem(label)
82  self._label.setFont(GraphItem._LABEL_FONT)
83  label_rect = self._label.boundingRect()
84  label_rect.moveCenter(label_center)
85  self._label.setPos(label_rect.x(), label_rect.y())
86  self._label.hoverEnterEvent = self._handle_hoverEnterEvent
87  self._label.hoverLeaveEvent = self._handle_hoverLeaveEvent
88  self._label.setAcceptHoverEvents(True)
89 
90  # spline specification according to
91  # http://www.graphviz.org/doc/info/attrs.html#k:splineType
92  coordinates = spline.split(' ')
93  # extract optional end_point
94  end_point = None
95  if (coordinates[0].startswith('e,')):
96  parts = coordinates.pop(0)[2:].split(',')
97  end_point = QPointF(float(parts[0]), -float(parts[1]))
98  # extract optional start_point
99  if (coordinates[0].startswith('s,')):
100  parts = coordinates.pop(0).split(',')
101 
102  # first point
103  parts = coordinates.pop(0).split(',')
104  point = QPointF(float(parts[0]), -float(parts[1]))
105  path = QPainterPath(point)
106 
107  while len(coordinates) > 2:
108  # extract triple of points for a cubic spline
109  parts = coordinates.pop(0).split(',')
110  point1 = QPointF(float(parts[0]), -float(parts[1]))
111  parts = coordinates.pop(0).split(',')
112  point2 = QPointF(float(parts[0]), -float(parts[1]))
113  parts = coordinates.pop(0).split(',')
114  point3 = QPointF(float(parts[0]), -float(parts[1]))
115  path.cubicTo(point1, point2, point3)
116 
117  self._arrow = None
118  if end_point is not None:
119  # draw arrow
120  self._arrow = QGraphicsPolygonItem()
121  polygon = QPolygonF()
122  polygon.append(point3)
123  offset = QPointF(end_point - point3)
124  corner1 = QPointF(-offset.y(), offset.x()) * 0.35
125  corner2 = QPointF(offset.y(), -offset.x()) * 0.35
126  polygon.append(point3 + corner1)
127  polygon.append(end_point)
128  polygon.append(point3 + corner2)
129  self._arrow.setPolygon(polygon)
130  self._arrow.hoverEnterEvent = self._handle_hoverEnterEvent
131  self._arrow.hoverLeaveEvent = self._handle_hoverLeaveEvent
132  self._arrow.setAcceptHoverEvents(True)
133 
134  self._path = QGraphicsPathItem(parent)
135  self._path.setPath(path)
136  self.addToGroup(self._path)
137 
138  self.set_node_color()
139  self.set_label_color()
140 
141  def add_to_scene(self, scene):
142  scene.addItem(self)
143  if self._label is not None:
144  scene.addItem(self._label)
145  if self._arrow is not None:
146  scene.addItem(self._arrow)
147 
148  def setToolTip(self, tool_tip):
149  super(EdgeItem, self).setToolTip(tool_tip)
150  if self._label is not None:
151  self._label.setToolTip(tool_tip)
152  if self._arrow is not None:
153  self._arrow.setToolTip(tool_tip)
154 
155  def add_sibling_edge(self, edge):
156  self._sibling_edges.add(edge)
157 
158  def set_node_color(self, color=None):
159  if color is None:
160  self._label_pen.setColor(self._default_text_color)
161  self._text_brush.setColor(self._default_color)
162  if self._shape_brush.isOpaque():
163  self._shape_brush.setColor(self._default_edge_color)
164  self._edge_pen.setColor(self._default_edge_color)
165  else:
166  self._label_pen.setColor(color)
167  self._text_brush.setColor(color)
168  if self._shape_brush.isOpaque():
169  self._shape_brush.setColor(color)
170  self._edge_pen.setColor(color)
171 
172  self._path.setPen(self._edge_pen)
173  if self._arrow is not None:
174  self._arrow.setBrush(self._shape_brush)
175  self._arrow.setPen(self._edge_pen)
176 
177  def set_label_color(self, color=None):
178  if color is None:
179  self._label_pen.setColor(self._default_text_color)
180  else:
181  self._label_pen.setColor(color)
182 
183  if self._label is not None:
184  self._label.setBrush(self._text_brush)
185  self._label.setPen(self._label_pen)
186 
187  def _handle_hoverEnterEvent(self, event):
188  # hovered edge item in red
189  self.set_node_color(self._COLOR_RED)
190  self.set_label_color(self._COLOR_RED)
191 
192  if self._highlight_level > 1:
193  if self.from_node != self.to_node:
194  # from-node in blue
195  self.from_node.set_node_color(self._COLOR_BLUE)
196  # to-node in green
197  self.to_node.set_node_color(self._COLOR_GREEN)
198  else:
199  # from-node/in-node in teal
200  self.from_node.set_node_color(self._COLOR_TEAL)
201  self.to_node.set_node_color(self._COLOR_TEAL)
202  if self._highlight_level > 2:
203  # sibling edges in orange
204  for sibling_edge in self._sibling_edges:
205  sibling_edge.set_node_color(self._COLOR_ORANGE)
206 
207  def _handle_hoverLeaveEvent(self, event):
208  self.set_node_color()
209  self.set_label_color()
210  if self._highlight_level > 1:
211  self.from_node.set_node_color()
212  self.to_node.set_node_color()
213  if self._highlight_level > 2:
214  for sibling_edge in self._sibling_edges:
215  sibling_edge.set_node_color()
def add_sibling_edge(self, edge)
Definition: edge_item.py:155
def __init__(self, highlight_level, spline, label_center, label, from_node, to_node, parent=None, penwidth=1, edge_color=None, style='solid')
Definition: edge_item.py:51
def setToolTip(self, tool_tip)
Definition: edge_item.py:148
def set_node_color(self, color=None)
Definition: edge_item.py:158
def set_label_color(self, color=None)
Definition: edge_item.py:177
def _handle_hoverEnterEvent(self, event)
Definition: edge_item.py:187
def add_to_scene(self, scene)
Definition: edge_item.py:141
def _handle_hoverLeaveEvent(self, event)
Definition: edge_item.py:207


qt_dotgraph
Author(s): Thibault Kruse, Dirk Thomas
autogenerated on Tue Apr 13 2021 03:03:12