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
00032
00033
00034
00035 from math import floor
00036 import rospy
00037
00038 from python_qt_binding.QtCore import QPointF, Signal, Slot
00039 from python_qt_binding.QtGui import (QColor, QGraphicsPixmapItem,
00040 QGraphicsView, QIcon, QGraphicsScene)
00041
00042 import util_robot_monitor as util
00043
00044
00045 class TimelineView(QGraphicsView):
00046 """
00047 This class draws a graphical representation of a timeline.
00048
00049 This is ONLY the bar and colored boxes.
00050
00051 When you instantiate this class, do NOT forget to call set_init_data to
00052 set necessary data.
00053 """
00054
00055 redraw = Signal()
00056
00057 def __init__(self, parent):
00058 """Cannot take args other than parent due to loadUi limitation."""
00059
00060 super(TimelineView, self).__init__()
00061 self._parent = parent
00062 self._timeline_marker = QIcon.fromTheme('system-search')
00063
00064 self._min = 0
00065 self._max = 0
00066 self._xpos_marker = 5
00067
00068 self._timeline_marker_width = 15
00069 self._timeline_marker_height = 15
00070 self._last_marker_at = 2
00071
00072 self.redraw.connect(self._slot_redraw)
00073
00074 self._timeline = None
00075
00076 self.setUpdatesEnabled(True)
00077 self._scene = QGraphicsScene(self)
00078 self.setScene(self._scene)
00079
00080 def set_timeline(self, timeline, name=None):
00081 assert(self._timeline is None)
00082 self._name = name
00083 self._timeline = timeline
00084 self._timeline.message_updated.connect(self._updated)
00085
00086 @Slot()
00087 def _updated(self):
00088 """
00089 Update the widget whenever we receive a new message
00090 """
00091
00092 self._min = 0
00093 self._max = len(self._timeline)-1
00094
00095
00096 self._xpos_marker = self._timeline.get_position()
00097
00098
00099 self.redraw.emit()
00100
00101 def mouseReleaseEvent(self, event):
00102 """
00103 :type event: QMouseEvent
00104 """
00105 xpos = self.pos_from_x(event.x())
00106 self.set_marker_pos(xpos)
00107
00108 def mousePressEvent(self, event):
00109 """
00110 :type event: QMouseEvent
00111 """
00112 assert(self._timeline is not None)
00113
00114 self._timeline.set_paused(True)
00115
00116 xpos = self.pos_from_x(event.x())
00117 self.set_marker_pos(xpos)
00118
00119 def mouseMoveEvent(self, event):
00120 """
00121 :type event: QMouseEvent
00122 """
00123 xpos = self.pos_from_x(event.x())
00124 self.set_marker_pos(xpos)
00125
00126 def pos_from_x(self, x):
00127 """
00128 Get the index in the timeline from the mouse click position
00129
00130 :param x: Position relative to self widget.
00131 :return: Index
00132 """
00133 width = self.size().width()
00134
00135 width_cell = width / float(len(self._timeline))
00136 return int(floor(x / width_cell))
00137
00138 def set_marker_pos(self, xpos):
00139 """
00140 Set marker position from index
00141
00142 :param xpos: Marker index
00143 """
00144 assert(self._timeline is not None)
00145 self._xpos_marker = self._clamp(xpos, self._min, self._max)
00146
00147 if self._xpos_marker == self._last_marker_at:
00148
00149 return
00150 elif self._xpos_marker >= len(self._timeline):
00151
00152 return
00153
00154 self._last_marker_at = self._xpos_marker
00155
00156
00157
00158 self._timeline.set_position(self._xpos_marker)
00159
00160
00161 self.redraw.emit()
00162
00163 def _clamp(self, val, min, max):
00164 """
00165 Judge if val is within the range given by min & max.
00166 If not, return either min or max.
00167
00168 :type val: any number format
00169 :type min: any number format
00170 :type max: any number format
00171 :rtype: int
00172 """
00173 if (val < min):
00174 return min
00175 if (val > max):
00176 return max
00177 return val
00178
00179 @Slot()
00180 def _slot_redraw(self):
00181 """
00182 Gets called either when new msg comes in or when marker is moved by
00183 user.
00184 """
00185 self._scene.clear()
00186
00187 qsize = self.size()
00188 width_tl = qsize.width()
00189
00190 w = width_tl / float(max(len(self._timeline), 1))
00191 is_enabled = self.isEnabled()
00192
00193 if self._timeline is not None:
00194 for i, m in enumerate(self._timeline):
00195 h = self.viewport().height()
00196
00197
00198 qcolor = QColor('grey')
00199 if is_enabled:
00200 qcolor = self._get_color_for_value(m)
00201
00202
00203
00204
00205
00206
00207 self._scene.addRect(w * i, 0, w, h, QColor('white'), qcolor)
00208
00209
00210 xpos_marker = (self._xpos_marker * w +
00211 (w / 2.0) - (self._timeline_marker_width / 2.0))
00212 pos_marker = QPointF(xpos_marker, 0)
00213
00214
00215
00216 timeline_marker = self._instantiate_tl_icon()
00217 timeline_marker.setPos(pos_marker)
00218 self._scene.addItem(timeline_marker)
00219
00220 def _instantiate_tl_icon(self):
00221 timeline_marker_icon = QIcon.fromTheme('system-search')
00222 timeline_marker_icon_pixmap = timeline_marker_icon.pixmap(
00223 self._timeline_marker_width,
00224 self._timeline_marker_height)
00225 return QGraphicsPixmapItem(timeline_marker_icon_pixmap)
00226
00227 def _get_color_for_value(self, msg):
00228 """
00229 :type msg: DiagnosticArray
00230 """
00231
00232 if self._name is not None:
00233
00234 status = util.get_status_by_name(msg, self._name)
00235 if status is not None:
00236 return util.level_to_color(status.level)
00237 else:
00238 return QColor('grey')
00239 return util.get_color_for_message(msg)
rqt_robot_monitor
Author(s): Austin Hendrix, Isaac Saito, Ze'ev Klapow, Kevin Watts, Josh Faust
autogenerated on Fri Aug 28 2015 12:50:48