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 import os
00034
00035 from python_qt_binding import loadUi
00036 from python_qt_binding.QtCore import Qt
00037 from python_qt_binding.QtGui import QIcon
00038 from python_qt_binding.QtWidgets import (QAction, QMenu, QMessageBox,
00039 QTreeView, QWidget)
00040 import roslib
00041 import rosmsg
00042 import rospkg
00043 import rospy
00044
00045
00046 from .messages_tree_view import MessagesTreeView
00047 from rqt_py_common import rosaction
00048 from rqt_console.text_browse_dialog import TextBrowseDialog
00049
00050
00051 class MessagesWidget(QWidget):
00052
00053 """
00054 This class is intended to be able to handle msg, srv & action (actionlib).
00055 The name of the class is kept to use message, by following the habit of
00056 rosmsg (a script that can handle both msg & srv).
00057 """
00058
00059 def __init__(self, mode=rosmsg.MODE_MSG,
00060 pkg_name='rqt_msg',
00061 ui_filename='messages.ui'):
00062 """
00063 :param ui_filename: This Qt-based .ui file must have elements that are
00064 referred from this class. Otherwise unexpected
00065 errors are likely to happen. Best way to avoid that
00066 situation when you want to give your own .ui file
00067 is to implement all Qt components in
00068 rqt_msg/resource/message.ui file.
00069 """
00070
00071 super(MessagesWidget, self).__init__()
00072 self._rospack = rospkg.RosPack()
00073 ui_file = os.path.join(self._rospack.get_path(pkg_name), 'resource', ui_filename)
00074 loadUi(ui_file, self, {'MessagesTreeView': MessagesTreeView})
00075 self.setObjectName(ui_filename)
00076 self._mode = mode
00077
00078 self._add_button.setIcon(QIcon.fromTheme('list-add'))
00079 self._add_button.clicked.connect(self._add_message)
00080 self._refresh_packages(mode)
00081 self._refresh_msgs(self._package_combo.itemText(0))
00082 self._package_combo.currentIndexChanged[str].connect(self._refresh_msgs)
00083 self._messages_tree.mousePressEvent = self._handle_mouse_press
00084
00085 self._browsers = []
00086
00087 def _refresh_packages(self, mode=rosmsg.MODE_MSG):
00088 if (self._mode == rosmsg.MODE_MSG) or self._mode == rosmsg.MODE_SRV:
00089 packages = sorted([pkg_tuple[0] for pkg_tuple in
00090 rosmsg.iterate_packages(self._rospack, self._mode)])
00091 elif self._mode == rosaction.MODE_ACTION:
00092 packages = sorted([pkg_tuple[0]
00093 for pkg_tuple in rosaction.iterate_packages(
00094 self._rospack, self._mode)])
00095 self._package_list = packages
00096 rospy.logdebug('pkgs={}'.format(self._package_list))
00097 self._package_combo.clear()
00098 self._package_combo.addItems(self._package_list)
00099 self._package_combo.setCurrentIndex(0)
00100
00101 def _refresh_msgs(self, package=None):
00102 if package is None or len(package) == 0:
00103 return
00104 self._msgs = []
00105 if (self._mode == rosmsg.MODE_MSG or
00106 self._mode == rosaction.MODE_ACTION):
00107 msg_list = rosmsg.list_msgs(package)
00108 elif self._mode == rosmsg.MODE_SRV:
00109 msg_list = rosmsg.list_srvs(package)
00110
00111 rospy.logdebug(
00112 '_refresh_msgs package={} msg_list={}'.format(package, msg_list))
00113 for msg in msg_list:
00114 if (self._mode == rosmsg.MODE_MSG or
00115 self._mode == rosaction.MODE_ACTION):
00116 msg_class = roslib.message.get_message_class(msg)
00117 elif self._mode == rosmsg.MODE_SRV:
00118 msg_class = roslib.message.get_service_class(msg)
00119
00120 rospy.logdebug('_refresh_msgs msg_class={}'.format(msg_class))
00121
00122 if msg_class is not None:
00123 self._msgs.append(msg)
00124
00125 self._msgs = [x.split('/')[1] for x in self._msgs]
00126
00127 self._msgs_combo.clear()
00128 self._msgs_combo.addItems(self._msgs)
00129
00130 def _add_message(self):
00131 if self._msgs_combo.count() == 0:
00132 return
00133 msg = (self._package_combo.currentText() +
00134 '/' + self._msgs_combo.currentText())
00135
00136 rospy.logdebug('_add_message msg={}'.format(msg))
00137
00138 if (self._mode == rosmsg.MODE_MSG or
00139 self._mode == rosaction.MODE_ACTION):
00140 msg_class = roslib.message.get_message_class(msg)()
00141 if self._mode == rosmsg.MODE_MSG:
00142 text_tree_root = 'Msg Root'
00143 elif self._mode == rosaction.MODE_ACTION:
00144 text_tree_root = 'Action Root'
00145 self._messages_tree.model().add_message(msg_class,
00146 self.tr(text_tree_root), msg, msg)
00147
00148 elif self._mode == rosmsg.MODE_SRV:
00149 msg_class = roslib.message.get_service_class(msg)()
00150 self._messages_tree.model().add_message(msg_class._request_class,
00151 self.tr('Service Request'),
00152 msg, msg)
00153 self._messages_tree.model().add_message(msg_class._response_class,
00154 self.tr('Service Response'),
00155 msg, msg)
00156 self._messages_tree._recursive_set_editable(
00157 self._messages_tree.model().invisibleRootItem(), False)
00158
00159 def _handle_mouse_press(self, event,
00160 old_pressEvent=QTreeView.mousePressEvent):
00161 if (event.buttons() & Qt.RightButton and
00162 event.modifiers() == Qt.NoModifier):
00163 self._rightclick_menu(event)
00164 event.accept()
00165 return old_pressEvent(self._messages_tree, event)
00166
00167 def _rightclick_menu(self, event):
00168 """
00169 :type event: QEvent
00170 """
00171
00172
00173
00174
00175
00176 selected = self._messages_tree.selectedIndexes()
00177 if len(selected) == 0:
00178 return
00179
00180 menu = QMenu()
00181 text_action = QAction(self.tr('View Text'), menu)
00182 menu.addAction(text_action)
00183 raw_action = QAction(self.tr('View Raw'), menu)
00184 menu.addAction(raw_action)
00185 remove_action = QAction(self.tr('Remove message'), menu)
00186 menu.addAction(remove_action)
00187
00188 action = menu.exec_(event.globalPos())
00189
00190 if action == raw_action or action == text_action:
00191 rospy.logdebug('_rightclick_menu selected={}'.format(selected))
00192 selected_type = selected[1].data()
00193
00194 if selected_type[-2:] == '[]':
00195 selected_type = selected_type[:-2]
00196 browsetext = None
00197 try:
00198 if (self._mode == rosmsg.MODE_MSG or
00199 self._mode == rosaction.MODE_ACTION):
00200 browsetext = rosmsg.get_msg_text(selected_type,
00201 action == raw_action)
00202 elif self._mode == rosmsg.MODE_SRV:
00203 browsetext = rosmsg.get_srv_text(selected_type,
00204 action == raw_action)
00205
00206 else:
00207 raise
00208 except rosmsg.ROSMsgException as e:
00209 QMessageBox.warning(self, self.tr('Warning'),
00210 self.tr('The selected item component ' +
00211 'does not have text to view.'))
00212 if browsetext is not None:
00213 self._browsers.append(TextBrowseDialog(browsetext,
00214 self._rospack))
00215 self._browsers[-1].show()
00216
00217 if action == remove_action:
00218 self._messages_tree.model().removeRow(selected[0].row())
00219
00220 def cleanup_browsers_on_close(self):
00221 for browser in self._browsers:
00222 browser.close()