edge_item.py
Go to the documentation of this file.
00001 # Copyright (c) 2011, Dirk Thomas, TU Darmstadt
00002 # All rights reserved.
00003 #
00004 # Redistribution and use in source and binary forms, with or without
00005 # modification, are permitted provided that the following conditions
00006 # are met:
00007 #
00008 #   * Redistributions of source code must retain the above copyright
00009 #     notice, this list of conditions and the following disclaimer.
00010 #   * Redistributions in binary form must reproduce the above
00011 #     copyright notice, this list of conditions and the following
00012 #     disclaimer in the documentation and/or other materials provided
00013 #     with the distribution.
00014 #   * Neither the name of the TU Darmstadt nor the names of its
00015 #     contributors may be used to endorse or promote products derived
00016 #     from this software without specific prior written permission.
00017 #
00018 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00019 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00020 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00021 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00022 # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00023 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00024 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00026 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00027 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00028 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00029 # POSSIBILITY OF SUCH DAMAGE.
00030 
00031 from python_qt_binding.QtCore import QPointF, Qt
00032 from python_qt_binding.QtGui import QBrush, QGraphicsPathItem, QGraphicsPolygonItem, QGraphicsSimpleTextItem, QPainterPath, QPen, QPolygonF
00033 
00034 from .graph_item import GraphItem
00035 
00036 
00037 class EdgeItem(GraphItem):
00038 
00039     _qt_pen_styles = {
00040         'dashed': Qt.DashLine,
00041         'dotted': Qt.DotLine,
00042         'solid': Qt.SolidLine,
00043     }
00044 
00045     def __init__(self, highlight_level, spline, label_center, label, from_node, to_node, parent=None, penwidth=1, edge_color=None, style='solid'):
00046         super(EdgeItem, self).__init__(highlight_level, parent)
00047 
00048         self.from_node = from_node
00049         self.from_node.add_outgoing_edge(self)
00050         self.to_node = to_node
00051         self.to_node.add_incoming_edge(self)
00052 
00053         self._default_edge_color = self._COLOR_BLACK
00054         if edge_color is not None:
00055             self._default_edge_color = edge_color
00056 
00057         self._default_text_color = self._COLOR_BLACK
00058         self._default_color = self._COLOR_BLACK
00059         self._text_brush = QBrush(self._default_color)
00060         self._shape_brush = QBrush(self._default_color)
00061         if style in ['dashed', 'dotted']:
00062             self._shape_brush = QBrush(Qt.transparent)
00063         self._label_pen = QPen()
00064         self._label_pen.setColor(self._default_text_color)
00065         self._label_pen.setJoinStyle(Qt.RoundJoin)
00066         self._edge_pen = QPen(self._label_pen)
00067         self._edge_pen.setWidth(penwidth)
00068         self._edge_pen.setColor(self._default_edge_color)
00069         self._edge_pen.setStyle(self._qt_pen_styles.get(style, Qt.SolidLine))
00070 
00071         self._sibling_edges = set()
00072 
00073         self._label = None
00074         if label is not None:
00075             self._label = QGraphicsSimpleTextItem(label)
00076             label_rect = self._label.boundingRect()
00077             label_rect.moveCenter(label_center)
00078             self._label.setPos(label_rect.x(), label_rect.y())
00079             self._label.hoverEnterEvent = self._handle_hoverEnterEvent
00080             self._label.hoverLeaveEvent = self._handle_hoverLeaveEvent
00081             self._label.setAcceptHoverEvents(True)
00082 
00083         # spline specification according to http://www.graphviz.org/doc/info/attrs.html#k:splineType
00084         coordinates = spline.split(' ')
00085         # extract optional end_point
00086         end_point = None
00087         if (coordinates[0].startswith('e,')):
00088             parts = coordinates.pop(0)[2:].split(',')
00089             end_point = QPointF(float(parts[0]), -float(parts[1]))
00090         # extract optional start_point
00091         if (coordinates[0].startswith('s,')):
00092             parts = coordinates.pop(0).split(',')
00093 
00094         # first point
00095         parts = coordinates.pop(0).split(',')
00096         point = QPointF(float(parts[0]), -float(parts[1]))
00097         path = QPainterPath(point)
00098 
00099         while len(coordinates) > 2:
00100             # extract triple of points for a cubic spline
00101             parts = coordinates.pop(0).split(',')
00102             point1 = QPointF(float(parts[0]), -float(parts[1]))
00103             parts = coordinates.pop(0).split(',')
00104             point2 = QPointF(float(parts[0]), -float(parts[1]))
00105             parts = coordinates.pop(0).split(',')
00106             point3 = QPointF(float(parts[0]), -float(parts[1]))
00107             path.cubicTo(point1, point2, point3)
00108 
00109         self._arrow = None
00110         if end_point is not None:
00111             # draw arrow
00112             self._arrow = QGraphicsPolygonItem()
00113             polygon = QPolygonF()
00114             polygon.append(point3)
00115             offset = QPointF(end_point - point3)
00116             corner1 = QPointF(-offset.y(), offset.x()) * 0.35
00117             corner2 = QPointF(offset.y(), -offset.x()) * 0.35
00118             polygon.append(point3 + corner1)
00119             polygon.append(end_point)
00120             polygon.append(point3 + corner2)
00121             self._arrow.setPolygon(polygon)
00122             self._arrow.hoverEnterEvent = self._handle_hoverEnterEvent
00123             self._arrow.hoverLeaveEvent = self._handle_hoverLeaveEvent
00124             self._arrow.setAcceptHoverEvents(True)
00125 
00126         self._path = QGraphicsPathItem()
00127         self._path.setPath(path)
00128         self.addToGroup(self._path)
00129 
00130         self.set_node_color()
00131         self.set_label_color()
00132 
00133     def add_to_scene(self, scene):
00134         scene.addItem(self)
00135         if self._label is not None:
00136             scene.addItem(self._label)
00137         if self._arrow is not None:
00138             scene.addItem(self._arrow)
00139 
00140     def setToolTip(self, tool_tip):
00141         super(EdgeItem, self).setToolTip(tool_tip)
00142         if self._label is not None:
00143             self._label.setToolTip(tool_tip)
00144         if self._arrow is not None:
00145             self._arrow.setToolTip(tool_tip)
00146 
00147     def add_sibling_edge(self, edge):
00148         self._sibling_edges.add(edge)
00149 
00150     def set_node_color(self, color=None):
00151         if color is None:
00152             self._label_pen.setColor(self._default_text_color)
00153             self._text_brush.setColor(self._default_color)
00154             if self._shape_brush.isOpaque():
00155                 self._shape_brush.setColor(self._default_color)
00156             self._edge_pen.setColor(self._default_edge_color)
00157         else:
00158             self._label_pen.setColor(color)
00159             self._text_brush.setColor(color)
00160             if self._shape_brush.isOpaque():
00161                 self._shape_brush.setColor(color)
00162             self._edge_pen.setColor(color)
00163 
00164         self._path.setPen(self._edge_pen)
00165         if self._arrow is not None:
00166             self._arrow.setBrush(self._shape_brush)
00167             self._arrow.setPen(self._edge_pen)
00168 
00169     def set_label_color(self, color=None):
00170         if color is None:
00171             self._label_pen.setColor(self._default_text_color)
00172         else:
00173             self._label_pen.setColor(color)
00174 
00175         if self._label is not None:
00176             self._label.setBrush(self._text_brush)
00177             self._label.setPen(self._label_pen)
00178 
00179     def _handle_hoverEnterEvent(self, event):
00180         # hovered edge item in red
00181         self.set_node_color(self._COLOR_RED)
00182 
00183         if self._highlight_level > 1:
00184             if self.from_node != self.to_node:
00185                 # from-node in blue
00186                 self.from_node.set_node_color(self._COLOR_BLUE)
00187                 # to-node in green
00188                 self.to_node.set_node_color(self._COLOR_GREEN)
00189             else:
00190                 # from-node/in-node in teal
00191                 self.from_node.set_node_color(self._COLOR_TEAL)
00192                 self.to_node.set_node_color(self._COLOR_TEAL)
00193         if self._highlight_level > 2:
00194             # sibling edges in orange
00195             for sibling_edge in self._sibling_edges:
00196                 sibling_edge.set_node_color(self._COLOR_ORANGE)
00197 
00198     def _handle_hoverLeaveEvent(self, event):
00199         self.set_node_color()
00200         if self._highlight_level > 1:
00201             self.from_node.set_node_color()
00202             self.to_node.set_node_color()
00203         if self._highlight_level > 2:
00204             for sibling_edge in self._sibling_edges:
00205                 sibling_edge.set_node_color()


qt_dotgraph
Author(s): Thibault Kruse
autogenerated on Fri Aug 28 2015 12:15:47