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