33 from __future__
import division
39 from tf2_msgs.srv
import FrameGraph
42 from python_qt_binding
import loadUi
43 from python_qt_binding.QtCore
import QFile, QIODevice, QObject, Qt, Signal
44 from python_qt_binding.QtGui
import QIcon, QImage, QPainter
45 from python_qt_binding.QtWidgets
import QFileDialog, QGraphicsScene, QWidget
46 from python_qt_binding.QtSvg
import QSvgGenerator
52 from .dotcode_tf
import RosTfTreeDotcodeGenerator
57 _deferred_fit_in_view = Signal()
60 super(RosTfTree, self).
__init__(context)
63 self.setObjectName(
'RosTfTree')
81 ui_file = os.path.join(rp.get_path(
'rqt_tf_tree'),
'resource',
'RosTfTree.ui')
82 loadUi(ui_file, self.
_widget, {
'InteractiveGraphicsView': InteractiveGraphicsView})
83 self._widget.setObjectName(
'RosTfTreeUi')
84 if context.serial_number() > 1:
85 self._widget.setWindowTitle(self._widget.windowTitle() + (
' (%d)' % context.serial_number()))
88 self._scene.setBackgroundBrush(Qt.white)
89 self._widget.graphics_view.setScene(self.
_scene)
91 self._widget.clear_buffer_push_button.setIcon(QIcon.fromTheme(
'edit-delete'))
92 self._widget.clear_buffer_push_button.pressed.connect(self.
_clear_buffer)
94 self._widget.refresh_graph_push_button.setIcon(QIcon.fromTheme(
'view-refresh'))
95 self._widget.refresh_graph_push_button.pressed.connect(self.
_update_tf_graph)
99 self._widget.fit_in_view_push_button.setIcon(QIcon.fromTheme(
'zoom-original'))
100 self._widget.fit_in_view_push_button.pressed.connect(self.
_fit_in_view)
102 self._widget.load_dot_push_button.setIcon(QIcon.fromTheme(
'document-open'))
103 self._widget.load_dot_push_button.pressed.connect(self.
_load_dot)
104 self._widget.save_dot_push_button.setIcon(QIcon.fromTheme(
'document-save-as'))
105 self._widget.save_dot_push_button.pressed.connect(self.
_save_dot)
106 self._widget.save_as_svg_push_button.setIcon(QIcon.fromTheme(
'document-save-as'))
107 self._widget.save_as_svg_push_button.pressed.connect(self.
_save_svg)
108 self._widget.save_as_image_push_button.setIcon(QIcon.fromTheme(
'image-x-generic'))
109 self._widget.save_as_image_push_button.pressed.connect(self.
_save_image)
113 self._deferred_fit_in_view.emit()
115 context.add_widget(self.
_widget)
120 instance_settings.set_value(
'auto_fit_graph_check_box_state',
121 self._widget.auto_fit_graph_check_box.isChecked())
122 instance_settings.set_value(
'highlight_connections_check_box_state',
123 self._widget.highlight_connections_check_box.isChecked())
126 self._widget.auto_fit_graph_check_box.setChecked(
127 instance_settings.value(
'auto_fit_graph_check_box_state',
True)
in [
True,
'true'])
128 self._widget.highlight_connections_check_box.setChecked(
129 instance_settings.value(
'highlight_connections_check_box_state',
True)
in [
True,
'true'])
134 self.tf2_buffer_.clear()
148 rospy.wait_for_service(
'~tf2_frames')
149 tf2_frame_srv = rospy.ServiceProxy(
'~tf2_frames', FrameGraph)
150 return self.dotcode_generator.generate_dotcode(dotcode_factory=self.
dotcode_factory,
151 tf2_frame_srv=tf2_frame_srv,
152 force_refresh=force_refresh)
166 if self._widget.highlight_connections_check_box.isChecked():
174 for node_item
in nodes.values():
175 self._scene.addItem(node_item)
176 for edge_items
in edges.values():
177 for edge_item
in edge_items:
178 edge_item.add_to_scene(self.
_scene)
180 self._scene.setSceneRect(self._scene.itemsBoundingRect())
181 if self._widget.auto_fit_graph_check_box.isChecked():
185 if file_name
is None:
186 file_name, _ = QFileDialog.getOpenFileName(
188 self.tr(
'Open graph from file'),
190 self.tr(
'DOT graph (*.dot)'))
191 if file_name
is None or file_name ==
'':
195 fhandle = open(file_name,
'rb')
196 dotcode = fhandle.read()
204 self._widget.graphics_view.fitInView(self._scene.itemsBoundingRect(),
208 file_name, _ = QFileDialog.getSaveFileName(self.
_widget,
209 self.tr(
'Save as DOT'),
211 self.tr(
'DOT graph (*.dot)'))
212 if file_name
is None or file_name ==
'':
215 file = QFile(file_name)
216 if not file.open(QIODevice.WriteOnly | QIODevice.Text):
223 file_name, _ = QFileDialog.getSaveFileName(
225 self.tr(
'Save as SVG'),
227 self.tr(
'Scalable Vector Graphic (*.svg)'))
228 if file_name
is None or file_name ==
'':
231 generator = QSvgGenerator()
232 generator.setFileName(file_name)
233 generator.setSize((self._scene.sceneRect().size() * 2.0).toSize())
235 painter = QPainter(generator)
236 painter.setRenderHint(QPainter.Antialiasing)
237 self._scene.render(painter)
241 file_name, _ = QFileDialog.getSaveFileName(
243 self.tr(
'Save as image'),
245 self.tr(
'Image (*.bmp *.jpg *.png *.tiff)'))
246 if file_name
is None or file_name ==
'':
249 img = QImage((self._scene.sceneRect().size() * 2.0).toSize(),
250 QImage.Format_ARGB32_Premultiplied)
251 painter = QPainter(img)
252 painter.setRenderHint(QPainter.Antialiasing)
253 self._scene.render(painter)
def _refresh_tf_graph(self)
def _generate_tool_tip(self, url)
def _load_dot(self, file_name=None)
def _update_tf_graph(self)
def _update_graph_view(self, dotcode)
def restore_settings(self, plugin_settings, instance_settings)
def __init__(self, context)
def _generate_dotcode(self)
def _redraw_graph_view(self)
def save_settings(self, plugin_settings, instance_settings)