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