def __init__(self, parent, name, timeline): """ :param name: Name of inspecting diagnostic status :param timeline: Timeline object from which a status is fetched """ #TODO(Isaac) UI construction that currently is done in this method, # needs to be done in .ui file. super(InspectorWindow, self).__init__(parent=parent) self.setWindowTitle(name) self._name = name self.layout_vertical = QVBoxLayout(self) self.disp = StatusSnapshot(parent=self) self.layout_vertical.addWidget(self.disp, 1) self._message_updated_processing = False self._queue_updated_processing = False self.timeline = timeline self.timeline.message_updated.connect( self.message_updated, Qt.DirectConnection) self.timeline.queue_updated.connect( self.queue_updated, Qt.DirectConnection) self._message_updated.connect( self._signal_message_updated, Qt.QueuedConnection) self._queue_updated.connect( self._signal_queue_updated, Qt.QueuedConnection) self.timeline_pane = TimelinePane(self, self.timeline.paused) self.timeline_pane.pause_changed.connect(self.timeline.set_paused) self.timeline_pane.position_changed.connect(self.timeline.set_position) self.timeline.pause_changed.connect(self.timeline_pane.set_paused) self.timeline.position_changed.connect(self.timeline_pane.set_position) self.layout_vertical.addWidget(self.timeline_pane, 0) self.snapshot = QPushButton("Snapshot") self.snapshot.clicked.connect(self._take_snapshot) self.layout_vertical.addWidget(self.snapshot) self.snaps = [] self.setLayout(self.layout_vertical) # TODO better to be configurable where to appear. self.resize(400, 600)
class InspectorWindow(QWidget): closed = Signal(str) _message_updated = Signal(dict) _queue_updated = Signal() def __init__(self, parent, name, timeline): """ :param name: Name of inspecting diagnostic status :param timeline: Timeline object from which a status is fetched """ #TODO(Isaac) UI construction that currently is done in this method, # needs to be done in .ui file. super(InspectorWindow, self).__init__(parent=parent) self.setWindowTitle(name) self._name = name self.layout_vertical = QVBoxLayout(self) self.disp = StatusSnapshot(parent=self) self.layout_vertical.addWidget(self.disp, 1) self._message_updated_processing = False self._queue_updated_processing = False self.timeline = timeline self.timeline.message_updated.connect( self.message_updated, Qt.DirectConnection) self.timeline.queue_updated.connect( self.queue_updated, Qt.DirectConnection) self._message_updated.connect( self._signal_message_updated, Qt.QueuedConnection) self._queue_updated.connect( self._signal_queue_updated, Qt.QueuedConnection) self.timeline_pane = TimelinePane(self, self.timeline.paused) self.timeline_pane.pause_changed.connect(self.timeline.set_paused) self.timeline_pane.position_changed.connect(self.timeline.set_position) self.timeline.pause_changed.connect(self.timeline_pane.set_paused) self.timeline.position_changed.connect(self.timeline_pane.set_position) self.layout_vertical.addWidget(self.timeline_pane, 0) self.snapshot = QPushButton("Snapshot") self.snapshot.clicked.connect(self._take_snapshot) self.layout_vertical.addWidget(self.snapshot) self.snaps = [] self.setLayout(self.layout_vertical) # TODO better to be configurable where to appear. self.resize(400, 600) def closeEvent(self, event): """ called when this window is closed Calls close on all snapshots, and emits the closed signal """ # TODO: are snapshots kept around even after they're closed? # this appears to work even if the user closes some snapshots, # and they're still left in the internal array for snap in self.snaps: snap.close() self.closed.emit(self._name) @Slot() def queue_updated(self): ''' This method just calls _signal_queue_updated in 'best effort' manner. This method should be called by signal with DirectConnection. ''' if self._queue_updated_processing: return self._queue_updated_processing = True self._queue_updated.emit() @Slot() def _signal_queue_updated(self): # update timeline pane # collect worst status levels for each history status = self.timeline.get_all_status_by_name(self._name) self.timeline_pane.set_levels([s.level for s in status]) self.timeline_pane.set_position(self.timeline.position) self.timeline_pane.redraw.emit() self._queue_updated_processing = False @Slot(dict) def message_updated(self, status): ''' This method just calls _signal_message_updated in 'best effort' manner. This method should be called by signal with DirectConnection. ''' if self._message_updated_processing: return self._message_updated_processing = True self._message_updated.emit(status) @Slot(dict) def _signal_message_updated(self, status): rospy.logdebug('InspectorWin message_updated') status = status[self._name] scroll_value = self.disp.verticalScrollBar().value() self.status = status self.disp.write_status.emit(status) if self.disp.verticalScrollBar().maximum() < scroll_value: scroll_value = self.disp.verticalScrollBar().maximum() self.disp.verticalScrollBar().setValue(scroll_value) self._message_updated_processing = False def _take_snapshot(self): snap = StatusSnapshot(status=self.status) self.snaps.append(snap)
def _take_snapshot(self): snap = StatusSnapshot(status=self.status) self.snaps.append(snap)