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