def __init__(self, initial_topics=None, start_paused=False): super(PlotWidget, self).__init__() self.setObjectName('PlotWidget') self._initial_topics = initial_topics rp = rospkg.RosPack() ui_file = os.path.join(rp.get_path('rqt_plot'), 'resource', 'plot.ui') loadUi(ui_file, self) self.subscribe_topic_button.setIcon(QIcon.fromTheme('add')) self.remove_topic_button.setIcon(QIcon.fromTheme('remove')) self.pause_button.setIcon(QIcon.fromTheme('media-playback-pause')) self.clear_button.setIcon(QIcon.fromTheme('edit-clear')) self.data_plot = None self.subscribe_topic_button.setEnabled(False) if start_paused: self.pause_button.setChecked(True) self._topic_completer = TopicCompleter(self.topic_edit) self._topic_completer.update_topics() self.topic_edit.setCompleter(self._topic_completer) self._start_time = rospy.get_time() self._rosdata = {} self._remove_topic_menu = QMenu() # init and start update timer for plot self._update_plot_timer = QTimer(self) self._update_plot_timer.timeout.connect(self.update_plot)
def add_plugin(self, plugin_descriptor): base_path = plugin_descriptor.attributes().get('plugin_path') menu_manager = self._plugin_menu_manager # create submenus for group in plugin_descriptor.groups(): label = group['label'] if menu_manager.contains_menu(label): submenu = menu_manager.get_menu(label) else: submenu = QMenu(label, menu_manager.menu) menu_action = submenu.menuAction() self._enrich_action(menu_action, group, base_path) menu_manager.add_item(submenu) menu_manager = MenuManager(submenu) # create action action_attributes = plugin_descriptor.action_attributes() action = QAction(action_attributes['label'], menu_manager.menu) self._enrich_action(action, action_attributes, base_path) self._plugin_mapper.setMapping(action, plugin_descriptor.plugin_id()) action.triggered.connect(self._plugin_mapper.map) not_available = plugin_descriptor.attributes().get('not_available') if not_available: action.setEnabled(False) action.setStatusTip(self.tr('Plugin is not available: %s') % not_available) # add action to menu menu_manager.add_item(action)
def add_plugin(self, plugin_descriptor): base_path = plugin_descriptor.attributes().get('plugin_path') menu_manager = self._plugin_menu_manager # create submenus for group in plugin_descriptor.groups(): label = group['label'] if menu_manager.contains_menu(label): submenu = menu_manager.get_menu(label) else: submenu = QMenu(label, menu_manager.menu) menu_action = submenu.menuAction() self._enrich_action(menu_action, group, base_path) menu_manager.add_item(submenu) menu_manager = MenuManager(submenu) # create action action_attributes = plugin_descriptor.action_attributes() action = QAction(action_attributes['label'], menu_manager.menu) self._enrich_action(action, action_attributes, base_path) self._plugin_mapper.setMapping(action, plugin_descriptor.plugin_id()) action.triggered.connect(self._plugin_mapper.map) not_available = plugin_descriptor.attributes().get('not_available') if not_available: action.setEnabled(False) action.setStatusTip( self.tr('Plugin is not available: %s') % not_available) # add action to menu menu_manager.add_item(action)
def handle_header_view_customContextMenuRequested(self, pos): # create context menu menu = QMenu(self) action_toggle_auto_resize = menu.addAction('Auto-Resize') action_toggle_auto_resize.setCheckable(True) auto_resize_flag = ( self.header().resizeMode(0) == QHeaderView.ResizeToContents) action_toggle_auto_resize.setChecked(auto_resize_flag) action_toggle_sorting = menu.addAction('Sorting') action_toggle_sorting.setCheckable(True) action_toggle_sorting.setChecked(self.isSortingEnabled()) # show menu action = menu.exec_(self.header().mapToGlobal(pos)) # evaluate user action if action is action_toggle_auto_resize: if auto_resize_flag: self.header().setResizeMode(QHeaderView.Interactive) else: self.header().setResizeMode(QHeaderView.ResizeToContents) elif action is action_toggle_sorting: self.setSortingEnabled(not self.isSortingEnabled())
def positions_list_context_menu(self, group_type, pos): list_widget = self.list_widgets[group_type] list_item = list_widget.itemAt(pos) if list_item is None: return menu = QMenu() move_to = {} for group in self.robot_config.group_list(): if list_item._type == group.group_type: move_to[menu.addAction('move "%s"' % group.name)] = [group.name] # move_to[menu.addAction('move all')] = list(move_to.itervalues()) move_to[menu.addAction('move all')] = [ group_list[0] for group_list in list(move_to.itervalues()) ] result = menu.exec_(list_widget.mapToGlobal(pos)) if result in move_to: group_names = move_to[result] for group_name in group_names: target_positions = self.robot_config.groups[ group_name].adapt_to_side(list_item._data) self._motion_publisher.move_to_position( group_name, target_positions, self.time_factor_spin.value()) print '[Motion Editor] Moving %s to: %s' % ( group_name, zip(self.robot_config.groups[group_name].joints_sorted(), target_positions))
def glview_mouseReleaseEvent(self, event): if event.button() == Qt.RightButton: menu = QMenu(self._glview) action = QAction(self._glview.tr("Reset view"), self._glview) menu.addAction(action) action.triggered.connect(self.set_default_view) menu.exec_(self._glview.mapToGlobal(event.pos()))
def handle_header_view_customContextMenuRequested(self, pos): # create context menu menu = QMenu(self) action_toggle_auto_resize = menu.addAction('Auto-Resize') action_toggle_auto_resize.setCheckable(True) auto_resize_flag = (self.header().resizeMode(0) == QHeaderView.ResizeToContents) action_toggle_auto_resize.setChecked(auto_resize_flag) action_toggle_sorting = menu.addAction('Sorting') action_toggle_sorting.setCheckable(True) action_toggle_sorting.setChecked(self.isSortingEnabled()) # show menu action = menu.exec_(self.header().mapToGlobal(pos)) # evaluate user action if action is action_toggle_auto_resize: if auto_resize_flag: self.header().setResizeMode(QHeaderView.Interactive) else: self.header().setResizeMode(QHeaderView.ResizeToContents) elif action is action_toggle_sorting: self.setSortingEnabled(not self.isSortingEnabled())
def _create_context_menu_for_tag(self): if isinstance(self.hl, XmlHighlighter): tag = self.hl.get_tag_of_current_block(self.textCursor().block(), self.textCursor().positionInBlock()) if tag: try: menu = QMenu("ROS <%s>" % tag, self) menu.triggered.connect(self._context_activated) # create a menu with attributes menu_attr = QMenu("attributes", menu) attributes = sorted(list(set(XmlHighlighter.LAUNCH_ATTR[tag]))) for attr in attributes: action = menu_attr.addAction(attr.rstrip('=')) action.setData('%s""' % attr) menu.addMenu(menu_attr) # create a menu with tags tags = sorted(XmlHighlighter.LAUNCH_CHILDS[tag]) if tags: menu_tags = QMenu("tags", menu) for tag in tags: data = '<%s></%s>' % (tag, tag) if XmlHighlighter.LAUNCH_CHILDS[tag] else '<%s/>' % tag action = menu_tags.addAction(tag) action.setData(data) menu.addMenu(menu_tags) return menu except: import traceback print traceback.format_exc(1) return None return None
def __init__(self, menu_button): QMenu.__init__(self) self.button = menu_button try: rqt_icon_path = roslib.packages.find_resource('rqt_gui', 'rqt.png').pop() menu_button.setText('') menu_button.setIcon(QIcon(rqt_icon_path)) # creates a default config menu self.action_rqt_console = QAction(QIcon.fromTheme('mail-message-new'), "&Console", self, statusTip='"<p>Starts a python GUI plugin for displaying and filtering ' 'ROS log messages that is connected to the selected master.</p>"', triggered=self.on_show_console_clicked) self.addAction(self.action_rqt_console) self.action_rqt_logger_level = QAction(QIcon.fromTheme('format-indent-more'), "&Logger Level", self, statusTip='"<p>Starts a python GUI plugin for configuring the level of ' 'ROS loggers that is connected to the selected master.</p>"', triggered=self.on_show_logger_level_clicked) self.addAction(self.action_rqt_logger_level) self.action_rqt_tf_tree = QAction(QIcon.fromTheme('preferences-system-network'), "&TF Tree", self, statusTip='"<p>Starts a python GUI plugin for visualizing the TF tree' 'that is connected to the selected master.</p>"', triggered=self.on_show_tf_tree_clicked) self.addAction(self.action_rqt_tf_tree) self.action_rqt_ros_graph = QAction(QIcon(":/icons/button_graph.png"), "Ros &Graph", self, statusTip='"<p>Starts a python GUI plugin for visualizing the ROS computation graph' 'that is connected to the selected master</p>"', triggered=self.on_show_ros_graph_clicked) self.addAction(self.action_rqt_ros_graph) self.action_rosbag_record = QAction(QIcon.fromTheme('media-record'), "rosbag record", self, statusTip='"<p>Starts the rosbag record with selected topics</p>"', triggered=self.on_start_rosbag_clicked) self.addAction(self.action_rosbag_record) self.action_rqt_rviz = QAction(QIcon.fromTheme('image-x-generic'), "R&Viz", self, statusTip='"<p>Starts RViz</p>"', triggered=self.on_show_rviz_clicked) self.addAction(self.action_rqt_rviz) self.addSeparator() self.action_rqt = QAction(QIcon(rqt_icon_path), "&Rqt GUI", self, statusTip='"<p>Start the rqt GUI' 'that is connected to the selected master</p>"', triggered=self.on_start_rqt_clicked) self.addAction(self.action_rqt) menu_button.setMenu(self) except Exception as e: print '%s' % e menu_button.setEnabled(False) menu_button.setToolTip('rqt_gui not found! Please install rqt to use its plugins!')
def handle_header_view_customContextMenuRequested(self, pos): header = self.topics_tree_widget.header() # show context menu menu = QMenu(self) action_toggle_auto_resize = menu.addAction('Toggle Auto-Resize') action = menu.exec_(header.mapToGlobal(pos)) # evaluate user action if action is action_toggle_auto_resize: if header.resizeMode(0) == QHeaderView.ResizeToContents: header.setResizeMode(QHeaderView.Interactive) else: header.setResizeMode(QHeaderView.ResizeToContents)
def _on_header_menu(self, pos): header = self._widget.table_view.horizontalHeader() # Show context menu menu = QMenu(self._widget.table_view) action_toggle_auto_resize = menu.addAction('Toggle Auto-Resize') action = menu.exec_(header.mapToGlobal(pos)) # Evaluate user action if action is action_toggle_auto_resize: if header.resizeMode(0) == QHeaderView.ResizeToContents: header.setResizeMode(QHeaderView.Interactive) else: header.setResizeMode(QHeaderView.ResizeToContents)
def eventFilter(self, obj, event): if event.type() in self._event_callbacks: ret_val = self._event_callbacks[event.type()](obj, event) if ret_val is not None: return ret_val if event.type() == event.ContextMenu and obj == self.title_label: menu = QMenu(self) rename_action = menu.addAction(self.tr('Rename dock widget')) action = menu.exec_(self.mapToGlobal(event.pos())) if action == rename_action: self.title_label.hide() self.title_edit.setText(self.title_label.text()) self.title_edit.show() self.title_edit.setFocus() return True return QObject.eventFilter(self, obj, event)
def __init__(self, initial_topics=None, start_paused=False): super(PlotWidget, self).__init__() self.setObjectName('PlotWidget') self._initial_topics = initial_topics rp = rospkg.RosPack() ui_file = os.path.join(rp.get_path('rqt_plot'), 'resource', 'plot.ui') loadUi(ui_file, self) self.subscribe_topic_button.setIcon(QIcon.fromTheme('list-add')) self.remove_topic_button.setIcon(QIcon.fromTheme('list-remove')) self.pause_button.setIcon(QIcon.fromTheme('media-playback-pause')) self.clear_button.setIcon(QIcon.fromTheme('edit-clear')) self.data_plot = None self.subscribe_topic_button.setEnabled(False) if start_paused: self.pause_button.setChecked(True) self._topic_completer = TopicCompleter(self.topic_edit) self._topic_completer.update_topics() self.topic_edit.setCompleter(self._topic_completer) self._start_time = rospy.get_time() self._rosdata = {} self._remove_topic_menu = QMenu() # init and start update timer for plot self._update_plot_timer = QTimer(self) self._update_plot_timer.timeout.connect(self.update_plot)
def __init__(self, parent=None): ''' Creates the window, connects the signals and init the class. ''' QDockWidget.__init__(self, parent) # initialize parameter self.__current_path = os.path.expanduser('~') # load the UI file ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'LaunchFilesDockWidget.ui') loadUi(ui_file, self) # initialize the view for the launch files self.launchlist_model = LaunchListModel() self.launchlist_proxyModel = QSortFilterProxyModel(self) self.launchlist_proxyModel.setSourceModel(self.launchlist_model) self.xmlFileView.setModel(self.launchlist_proxyModel) self.xmlFileView.setAlternatingRowColors(True) self.xmlFileView.activated.connect(self.on_launch_selection_activated) self.xmlFileView.setDragDropMode(QAbstractItemView.DragOnly) self.xmlFileView.setDragEnabled(True) sm = self.xmlFileView.selectionModel() sm.selectionChanged.connect(self.on_xmlFileView_selection_changed) # self.searchPackageLine.setVisible(False) self.searchPackageLine.textChanged.connect(self.set_package_filter) self.searchPackageLine.focusInEvent = self._searchline_focusInEvent # connect to the button signals self.refreshXmlButton.clicked.connect(self.on_refresh_xml_clicked) self.editXmlButton.clicked.connect(self.on_edit_xml_clicked) self.newXmlButton.clicked.connect(self.on_new_xml_clicked) self.openXmlButton.clicked.connect(self.on_open_xml_clicked) self.transferButton.clicked.connect(self.on_transfer_file_clicked) self.loadXmlButton.clicked.connect(self.on_load_xml_clicked) self.loadXmlAsDefaultButton.clicked.connect(self.on_load_as_default) # creates a default config menu start_menu = QMenu(self) self.loadDeafaultAtHostAct = QAction( "&Load default config on host", self, statusTip="Loads the default config at given host", triggered=self.on_load_as_default_at_host) start_menu.addAction(self.loadDeafaultAtHostAct) self.loadXmlAsDefaultButton.setMenu(start_menu) # initialize the progress queue self.progress_queue = ProgressQueue(self.progressFrame_cfg, self.progressBar_cfg, self.progressCancelButton_cfg, 'Launch File')
def __init__(self, updater, config): ''' @param updater: A class that extends threading.Thread. @type updater: rqt_reconfigure.param_updater.ParamUpdater ''' super(EditorWidget, self).__init__() self._updater = updater self.param_name = config['name'] self.param_default = config['default'] self.param_description = config['description'] self.old_value = None self.cmenu = QMenu() self.cmenu.addAction(self.tr('Set to Default')).triggered.connect(self._set_to_default)
def _add_exclude_filter(self, filter_index=False): """ :param filter_index: if false then this function shows a QMenu to allow the user to choose a type of message filter. ''bool'' OR :param filter_index: the index of the filter to be added, ''int'' :return: if a filter was added then the index is returned, ''int'' OR :return: if no filter was added then None is returned, ''NoneType'' """ if filter_index is False: filter_index = -1 filter_select_menu = QMenu() for index in self._filter_factory_order: # flattens the _exclude filters list and only adds the item if it doesn't already exist if index in ['message', 'location'] or not self.filter_factory[index][1] in [type(item) for sublist in self._exclude_filters for item in sublist]: filter_select_menu.addAction(self.filter_factory[index][0]) action = filter_select_menu.exec_(QCursor.pos()) if action is None: return None for index in self._filter_factory_order: if self.filter_factory[index][0] == action.text(): filter_index = index if filter_index == -1: return None index = len(self._exclude_filters) newfilter = self.filter_factory[filter_index][1]() if len(self.filter_factory[filter_index]) >= 4: newwidget = self.filter_factory[filter_index][2](newfilter, self._rospack, self.filter_factory[filter_index][3]) else: newwidget = self.filter_factory[filter_index][2](newfilter, self._rospack) # pack the new filter tuple onto the filter list self._exclude_filters.append((newfilter, FilterWrapperWidget(newwidget, self.filter_factory[filter_index][0]), filter_index)) self._proxy_model.add_exclude_filter(newfilter) newfilter.filter_changed_signal.connect(self._proxy_model.handle_exclude_filters_changed) self._exclude_filters[index][1].delete_button.clicked.connect(self._delete_exclude_filter) self._model.rowsInserted.connect(self._exclude_filters[index][1].repopulate) # place the widget in the proper location self.exclude_table.insertRow(index) self.exclude_table.setCellWidget(index, 0, self._exclude_filters[index][1]) self.exclude_table.resizeColumnsToContents() self.exclude_table.resizeRowsToContents() newfilter.filter_changed_signal.emit() return index
def on_ctrl_list_tree_widget_customContextMenuRequested(self, pos): ctrlman_ns = self.cm_namespace_combo.currentText() item = self.ctrl_list_tree_widget.itemAt(pos) if item is None: return ctrl_name = item.data(0, Qt.UserRole) ctrl_state = self._ctrlers[ctrl_name]['state'] # show context menu menu = QMenu(self) if ctrl_state == 'running': action_stop = menu.addAction( QIcon.fromTheme('media-playback-stop'), 'Stop Controller') action_kill = menu.addAction(QIcon.fromTheme('list-remove'), 'Stop and Unload Controller') elif ctrl_state == 'stopped': action_start = menu.addAction( QIcon.fromTheme('media-playback-start'), 'Start Controller') action_unload = menu.addAction(QIcon.fromTheme('list-remove'), 'Unload Controller') action = menu.exec_(self.ctrl_list_tree_widget.mapToGlobal(pos)) # evaluate user action if ctrl_state == 'running': if action is action_stop: self.start_stop_controller(ctrlman_ns, ctrl_name, False) elif action is action_kill: self.start_stop_controller(ctrlman_ns, ctrl_name, False) self.unload_controller(ctrlman_ns, ctrl_name) elif ctrl_state == 'stopped': if action is action_start: self.start_stop_controller(ctrlman_ns, ctrl_name, True) elif action is action_unload: self.unload_controller(ctrlman_ns, ctrl_name)
def _create_context_substitution_menu(self, force_all=True): if isinstance(self.hl, XmlHighlighter): text = self.toPlainText() pos = self.textCursor().position() - 1 try: if force_all or (text[pos] == '$' or (text[pos] == '(' and text[pos - 1] == '$')): menu = QMenu("ROS substitution args", self) menu.triggered.connect(self._context_activated) for arg in self.SUBSTITUTION_ARGS: action = menu.addAction("%s" % arg) if force_all: action.setData("$(%s )" % arg) else: action.setData("(%s" % arg if text[pos] == '$' else "%s" % arg) return menu except Exception: pass return None
def _create_context_substitution_menu(self, force_all=True): if isinstance(self.hl, XmlHighlighter): text = self.toPlainText() pos = self.textCursor().position() - 1 try: if force_all or (text[pos] == '$' or (text[pos] == '(' and text[pos - 1] == '$')): menu = QMenu("ROS substitution args", self) menu.triggered.connect(self._context_activated) for arg in self.SUBSTITUTION_ARGS: action = menu.addAction("%s" % arg) if force_all: action.setData("$(%s )" % arg) else: action.setData("(%s" % arg if text[pos] == '$' else "%s" % arg) return menu except: pass return None
def _show_context_menu(self, item, global_pos): if item is None: return # show context menu menu = QMenu(self) action_item_expand = menu.addAction(QIcon.fromTheme('zoom-in'), "Expand All Children") action_item_collapse = menu.addAction(QIcon.fromTheme('zoom-out'), "Collapse All Children") action = menu.exec_(global_pos) # evaluate user action if action in (action_item_expand, action_item_collapse): expanded = (action is action_item_expand) def recursive_set_expanded(item): item.setExpanded(expanded) for index in range(item.childCount()): recursive_set_expanded(item.child(index)) recursive_set_expanded(item)
def contextMenuEvent(self, event): menu = QMenu() clip = menu.addAction('clip') clip.setEnabled(False) menu.addSeparator() remove = menu.addAction('remove clip') result = menu.exec_(event.screenPos()) if result == remove: self.scene().removeItem(self)
def positions_list_context_menu(self, group_type, pos): list_widget = self.list_widgets[group_type] list_item = list_widget.itemAt(pos) if list_item is None: return menu = QMenu() move_to = {} for group in self.robot_config.group_list(): if list_item._type == group.group_type: move_to[menu.addAction('move "%s"' % group.name)] = [group.name] # move_to[menu.addAction('move all')] = list(move_to.itervalues()) move_to[menu.addAction('move all')] = [group_list[0] for group_list in list(move_to.itervalues())] result = menu.exec_(list_widget.mapToGlobal(pos)) if result in move_to: group_names = move_to[result] for group_name in group_names: target_positions = self.robot_config.groups[group_name].adapt_to_side(list_item._data) self._motion_publisher.move_to_position(group_name, target_positions, self.time_factor_spin.value()) print '[Motion Editor] Moving %s to: %s' % (group_name, zip(self.robot_config.groups[group_name].joints_sorted(), target_positions))
def on_topics_tree_widget_customContextMenuRequested(self, pos): item = self.topics_tree_widget.itemAt(pos) if item is None: return # show context menu menu = QMenu(self) action_item_expand = menu.addAction(QIcon.fromTheme('zoom-in'), 'Expand All Children') action_item_collapse = menu.addAction(QIcon.fromTheme('zoom-out'), 'Collapse All Children') action = menu.exec_(self.topics_tree_widget.mapToGlobal(pos)) # evaluate user action if action in (action_item_expand, action_item_collapse): expanded = (action is action_item_expand) def recursive_set_expanded(item): item.setExpanded(expanded) for index in range(item.childCount()): recursive_set_expanded(item.child(index)) recursive_set_expanded(item)
def on_ctrl_list_tree_widget_customContextMenuRequested(self, pos): ctrlman_ns = self.cm_namespace_combo.currentText() item = self.ctrl_list_tree_widget.itemAt(pos) if item is None: return ctrl_name = item.data(0, Qt.UserRole) ctrl_state = self._ctrlers[ctrl_name]['state'] # show context menu menu = QMenu(self) if ctrl_state == 'running': action_stop = menu.addAction( QIcon.fromTheme('media-playback-stop'), 'Stop Controller') action_kill = menu.addAction( QIcon.fromTheme('list-remove'), 'Stop and Unload Controller') elif ctrl_state == 'stopped': action_start = menu.addAction( QIcon.fromTheme('media-playback-start'), 'Start Controller') action_unload = menu.addAction( QIcon.fromTheme('list-remove'), 'Unload Controller') action = menu.exec_(self.ctrl_list_tree_widget.mapToGlobal(pos)) # evaluate user action if ctrl_state == 'running': if action is action_stop: self.start_stop_controller(ctrlman_ns, ctrl_name, False) elif action is action_kill: self.start_stop_controller(ctrlman_ns, ctrl_name, False) self.unload_controller(ctrlman_ns, ctrl_name) elif ctrl_state == 'stopped': if action is action_start: self.start_stop_controller(ctrlman_ns, ctrl_name, True) elif action is action_unload: self.unload_controller(ctrlman_ns, ctrl_name)
def __init__(self, parent=None): ''' Creates the window, connects the signals and init the class. ''' QDockWidget.__init__(self, parent) # initialize parameter self.__current_path = os.path.expanduser('~') # load the UI file ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'LaunchFilesDockWidget.ui') loadUi(ui_file, self) # initialize the view for the launch files self.launchlist_model = LaunchListModel() self.launchlist_proxyModel = QSortFilterProxyModel(self) self.launchlist_proxyModel.setSourceModel(self.launchlist_model) self.xmlFileView.setModel(self.launchlist_proxyModel) self.xmlFileView.setAlternatingRowColors(True) self.xmlFileView.activated.connect(self.on_launch_selection_activated) self.xmlFileView.setDragDropMode(QAbstractItemView.DragOnly) self.xmlFileView.setDragEnabled(True) sm = self.xmlFileView.selectionModel() sm.selectionChanged.connect(self.on_xmlFileView_selection_changed) # self.searchPackageLine.setVisible(False) self.searchPackageLine.textChanged.connect(self.set_package_filter) self.searchPackageLine.focusInEvent = self._searchline_focusInEvent # connect to the button signals self.refreshXmlButton.clicked.connect(self.on_refresh_xml_clicked) self.editXmlButton.clicked.connect(self.on_edit_xml_clicked) self.newXmlButton.clicked.connect(self.on_new_xml_clicked) self.openXmlButton.clicked.connect(self.on_open_xml_clicked) self.transferButton.clicked.connect(self.on_transfer_file_clicked) self.loadXmlButton.clicked.connect(self.on_load_xml_clicked) self.loadXmlAsDefaultButton.clicked.connect(self.on_load_as_default) # creates a default config menu start_menu = QMenu(self) self.loadDeafaultAtHostAct = QAction("&Load default config on host", self, statusTip="Loads the default config at given host", triggered=self.on_load_as_default_at_host) start_menu.addAction(self.loadDeafaultAtHostAct) self.loadXmlAsDefaultButton.setMenu(start_menu) # initialize the progress queue self.progress_queue = ProgressQueue(self.progressFrame_cfg, self.progressBar_cfg, self.progressCancelButton_cfg)
def _on_ctrl_menu(self, pos): # Get data of selected controller row = self._widget.table_view.rowAt(pos.y()) if row < 0: return # Cursor is not under a valid item ctrl = self._controllers[row] # Show context menu menu = QMenu(self._widget.table_view) if ctrl.state == 'running': action_stop = menu.addAction(self._icons['stopped'], 'Stop') action_kill = menu.addAction(self._icons['uninitialized'], 'Stop and Unload') elif ctrl.state == 'stopped': action_start = menu.addAction(self._icons['running'], 'Start') action_unload = menu.addAction(self._icons['uninitialized'], 'Unload') elif ctrl.state == 'uninitialized': action_load = menu.addAction(self._icons['stopped'], 'Load') action_spawn = menu.addAction(self._icons['running'], 'Load and Start') action = menu.exec_(self._widget.table_view.mapToGlobal(pos)) # Evaluate user action if ctrl.state == 'running': if action is action_stop: self._stop_controller(ctrl.name) elif action is action_kill: self._stop_controller(ctrl.name) self._unload_controller(ctrl.name) elif ctrl.state == 'stopped': if action is action_start: self._start_controller(ctrl.name) elif action is action_unload: self._unload_controller(ctrl.name) elif ctrl.state == 'uninitialized': if action is action_load: self._load_controller(ctrl.name) if action is action_spawn: self._load_controller(ctrl.name) self._start_controller(ctrl.name)
def eventFilter(self, obj, event): if event.type() in self._event_callbacks: ret_val = self._event_callbacks[event.type()](obj, event) if ret_val is not None: return ret_val if event.type() == event.ContextMenu and obj == self.title_label: menu = QMenu(self) rename_action = menu.addAction(self.tr('Rename dock widget')) hide_action = QAction("Hide title bar", self) hide_action.setCheckable(True) hide_action.setChecked(self.hide_title_bar) if self._dock_widget.features() & QDockWidget.DockWidgetFloatable and \ self._dock_widget.features() & QDockWidget.DockWidgetMovable: menu.addAction(hide_action) action = menu.exec_(self.mapToGlobal(event.pos())) if action == rename_action: self.title_label.hide() self.title_edit.setText(self.title_label.text()) self.title_edit.show() self.title_edit.setFocus() if action == hide_action: self.hide_title_bar = not self.hide_title_bar return True return QObject.eventFilter(self, obj, event)
def contextMenuEvent(self, event): menu = QMenu() clip = menu.addAction('track') clip.setEnabled(False) menu.addSeparator() copy_to = {} for destination_track in self.scene().tracks(self._type): if destination_track is not self: copy_to[menu.addAction('copy track to "%s"' % destination_track.name())] = destination_track clear = menu.addAction('clear track') result = menu.exec_(event.screenPos()) if result == clear: self.clear() elif result in copy_to: destination_track = copy_to[result] destination_track.clear() for clip in self.clips(): destination_track.add_clip(clip.text(), clip.starttime(), clip.duration(), clip.data())
def _rightclick_menu(self, event): """ :type event: QEvent """ # QTreeview.selectedIndexes() returns 0 when no node is selected. # This can happen when after booting no left-click has been made yet # (ie. looks like right-click doesn't count). These lines are the # workaround for that problem. selected = self._messages_tree.selectedIndexes() if len(selected) == 0: return menu = QMenu() text_action = QAction(self.tr('View Text'), menu) menu.addAction(text_action) raw_action = QAction(self.tr('View Raw'), menu) menu.addAction(raw_action) action = menu.exec_(event.globalPos()) if action == raw_action or action == text_action: rospy.logdebug('_rightclick_menu selected={}'.format(selected)) selected_type = selected[1].data() if selected_type[-2:] == '[]': selected_type = selected_type[:-2] browsetext = None try: if (self._mode == rosmsg.MODE_MSG or self._mode == rosaction.MODE_ACTION): browsetext = rosmsg.get_msg_text(selected_type, action == raw_action) elif self._mode == rosmsg.MODE_SRV: browsetext = rosmsg.get_srv_text(selected_type, action == raw_action) else: raise except rosmsg.ROSMsgException, e: QMessageBox.warning( self, self.tr('Warning'), self.tr('The selected item component ' + 'does not have text to view.')) if browsetext is not None: self._browsers.append( TextBrowseDialog(browsetext, self._rospack)) self._browsers[-1].show()
def __init__(self, initial_topics=None, start_paused=False, buffer_length=100, use_poly=True, no_legend=False): super(Plot3DWidget, self).__init__() self.setObjectName('Plot3DWidget') self._buffer_length = buffer_length self._initial_topics = initial_topics rp = rospkg.RosPack() ui_file = os.path.join(rp.get_path('jsk_rqt_plugins'), 'resource', 'plot3d.ui') loadUi(ui_file, self) self.subscribe_topic_button.setIcon(QIcon.fromTheme('add')) self.remove_topic_button.setIcon(QIcon.fromTheme('remove')) self.pause_button.setIcon(QIcon.fromTheme('media-playback-pause')) self.clear_button.setIcon(QIcon.fromTheme('edit-clear')) self.data_plot = MatDataPlot3D(self, self._buffer_length, use_poly, no_legend) self.data_plot_layout.addWidget(self.data_plot) self.data_plot.autoscroll(self.autoscroll_checkbox.isChecked()) self.data_plot.dropEvent = self.dropEvent self.data_plot.dragEnterEvent = self.dragEnterEvent self.subscribe_topic_button.setEnabled(False) if start_paused: self.pause_button.setChecked(True) self._topic_completer = TopicCompleter(self.topic_edit) self._topic_completer.update_topics() self.topic_edit.setCompleter(self._topic_completer) self._start_time = rospy.get_time() self._rosdata = {} self._remove_topic_menu = QMenu() # init and start update timer for plot self._update_plot_timer = QTimer(self) self._update_plot_timer.timeout.connect(self.update_plot) if self._initial_topics: for topic_name in self._initial_topics: self.add_topic(topic_name) self._initial_topics = None
def _rightclick_menu(self, event): """ :type event: QEvent """ # QTreeview.selectedIndexes() returns 0 when no node is selected. # This can happen when after booting no left-click has been made yet # (ie. looks like right-click doesn't count). These lines are the # workaround for that problem. selected = self._messages_tree.selectedIndexes() if len(selected) == 0: return menu = QMenu() text_action = QAction(self.tr('View Text'), menu) menu.addAction(text_action) raw_action = QAction(self.tr('View Raw'), menu) menu.addAction(raw_action) action = menu.exec_(event.globalPos()) if action == raw_action or action == text_action: rospy.logdebug('_rightclick_menu selected={}'.format(selected)) selected_type = selected[1].data() if selected_type[-2:] == '[]': selected_type = selected_type[:-2] browsetext = None try: if (self._mode == rosmsg.MODE_MSG or self._mode == rosaction.MODE_ACTION): browsetext = rosmsg.get_msg_text(selected_type, action == raw_action) elif self._mode == rosmsg.MODE_SRV: browsetext = rosmsg.get_srv_text(selected_type, action == raw_action) else: raise except rosmsg.ROSMsgException, e: QMessageBox.warning(self, self.tr('Warning'), self.tr('The selected item component ' + 'does not have text to view.')) if browsetext is not None: self._browsers.append(TextBrowseDialog(browsetext, self._rospack)) self._browsers[-1].show()
def _open_context_menu(self, position): indexes = self.plugin_manager_widget.plugin_tree_view.selectedIndexes() level = -1 if len(indexes) > 0: level = 0 index = indexes[0] while index.parent().isValid(): index = index.parent() level += 1 menu = QMenu() if level == 0: expand_action = QAction(self.tr('Expand'), None) expand_action.triggered.connect( self.plugin_manager_widget.plugin_tree_view.expandAll) menu.addAction(expand_action) if level == 0 or level == 1: remove_action = QAction(self.tr('Remove'), None) remove_action.triggered.connect(self.remove_plugins) menu.addAction(remove_action) menu.exec_( self.plugin_manager_widget.plugin_tree_view.viewport().mapToGlobal( position))
def _open_context_menu(self, position): indexes = self.plugin_manager_widget.plugin_tree_view.selectedIndexes() level = -1 if len(indexes) > 0: level = 0 index = indexes[0] while index.parent().isValid(): index = index.parent() level += 1 menu = QMenu() if level == 0: expand_action = QAction(self.tr('Expand'), None) expand_action.triggered.connect(self.plugin_manager_widget.plugin_tree_view.expandAll) menu.addAction(expand_action) if level == 0 or level == 1: remove_action = QAction(self.tr('Remove'), None) remove_action.triggered.connect(self.remove_plugins) menu.addAction(remove_action) menu.exec_(self.plugin_manager_widget.plugin_tree_view.viewport().mapToGlobal(position))
def _rightclick_menu(self, event): """ Dynamically builds the rightclick menu based on the unique column data from the passed in datamodel and then launches it modally :param event: the mouse event object, ''QMouseEvent'' """ severities = {} for severity, label in Message.SEVERITY_LABELS.items(): if severity in self._model.get_unique_severities(): severities[severity] = label nodes = sorted(self._model.get_unique_nodes()) topics = sorted(self._model.get_unique_topics()) # menutext entries turned into menutext = [] menutext.append([self.tr('Exclude'), [[self.tr('Severity'), severities], [self.tr('Node'), nodes], [self.tr('Topic'), topics], [self.tr('Selected Message(s)')]]]) menutext.append([self.tr('Highlight'), [[self.tr('Severity'), severities], [self.tr('Node'), nodes], [self.tr('Topic'), topics], [self.tr('Selected Message(s)')]]]) menutext.append([self.tr('Copy Selected')]) menutext.append([self.tr('Browse Selected')]) menu = QMenu() submenus = [] subsubmenus = [] for item in menutext: if len(item) > 1: submenus.append(QMenu(item[0], menu)) for subitem in item[1]: if len(subitem) > 1: subsubmenus.append(QMenu(subitem[0], submenus[-1])) if isinstance(subitem[1], dict): for key in sorted(subitem[1].keys()): action = subsubmenus[-1].addAction(subitem[1][key]) action.setData(key) else: for subsubitem in subitem[1]: subsubmenus[-1].addAction(subsubitem) submenus[-1].addMenu(subsubmenus[-1]) else: submenus[-1].addAction(subitem[0]) menu.addMenu(submenus[-1]) else: menu.addAction(item[0]) action = menu.exec_(event.globalPos()) if action is None or action == 0: return elif action.text() == self.tr('Browse Selected'): self._show_browsers() elif action.text() == self.tr('Copy Selected'): rowlist = [] for current in self.table_view.selectionModel().selectedIndexes(): rowlist.append(self._proxy_model.mapToSource(current).row()) copytext = self._model.get_selected_text(rowlist) if copytext is not None: clipboard = QApplication.clipboard() clipboard.setText(copytext) elif action.text() == self.tr('Selected Message(s)'): if action.parentWidget().title() == self.tr('Highlight'): self._process_highlight_exclude_filter(action.text(), 'Message', False) elif action.parentWidget().title() == self.tr('Exclude'): self._process_highlight_exclude_filter(action.text(), 'Message', True) else: raise RuntimeError("Menu format corruption in ConsoleWidget._rightclick_menu()") else: # This processes the dynamic list entries (severity, node and topic) try: roottitle = action.parentWidget().parentWidget().title() except: raise RuntimeError("Menu format corruption in ConsoleWidget._rightclick_menu()") if roottitle == self.tr('Highlight'): self._process_highlight_exclude_filter(action.text(), action.parentWidget().title(), False) elif roottitle == self.tr('Exclude'): self._process_highlight_exclude_filter(action.text(), action.parentWidget().title(), True) else: raise RuntimeError("Unknown Root Action %s selected in ConsoleWidget._rightclick_menu()" % roottitle)
def handle_customContextMenuRequested(self, pos): # show context menu menu = QMenu(self) self._context_menu_add_actions(menu, pos) menu.exec_(self.mapToGlobal(pos))
class EditorWidget(QWidget): ''' This class is abstract -- its child classes should be instantiated. There exist two kinds of "update" methods: - _update_paramserver for Parameter Server. - update_value for the value displayed on GUI. ''' def __init__(self, updater, config): ''' @param updater: A class that extends threading.Thread. @type updater: rqt_reconfigure.param_updater.ParamUpdater ''' super(EditorWidget, self).__init__() self._updater = updater self.param_name = config['name'] self.param_default = config['default'] self.param_description = config['description'] self.old_value = None self.cmenu = QMenu() self.cmenu.addAction(self.tr('Set to Default')).triggered.connect(self._set_to_default) def _update_paramserver(self, value): ''' Update the value on Parameter Server. ''' if value != self.old_value: self.update_configuration(value) self.old_value = value def update_value(self, value): ''' To be implemented in subclass, but still used. Update the value that's displayed on the arbitrary GUI component based on user's input. This method is not called from the GUI thread, so any changes to QObjects will need to be done through a signal. ''' self.old_value = value def update_configuration(self, value): self._updater.update({self.param_name: value}) def display(self, grid): ''' Should be overridden in subclass. :type grid: QFormLayout ''' self._paramname_label.setText(self.param_name) # label_paramname = QLabel(self.param_name) # label_paramname.setWordWrap(True) self._paramname_label.setMinimumWidth(100) grid.addRow(self._paramname_label, self) self.setToolTip(self.param_description) self._paramname_label.setToolTip(self.param_description) self._paramname_label.contextMenuEvent = self.contextMenuEvent def close(self): ''' Should be overridden in subclass. ''' pass def _set_to_default(self): self._update_paramserver(self.param_default) def contextMenuEvent(self, e): self.cmenu.exec_(e.globalPos())
def __init__(self, timeline, event, menu_topic): super(TimelinePopupMenu, self).__init__() self.parent = timeline self.timeline = timeline if menu_topic is not None: self.setTitle(menu_topic) self._menu_topic = menu_topic else: self._menu_topic = None self._reset_timeline = self.addAction('Reset Timeline') self._play_all = self.addAction('Play All Messages') self._play_all.setCheckable(True) self._play_all.setChecked(self.timeline.play_all) self.addSeparator() self._renderers = self.timeline._timeline_frame.get_renderers() self._thumbnail_actions = [] # create thumbnail menu items if menu_topic is None: submenu = self.addMenu('Thumbnails...') self._thumbnail_show_action = submenu.addAction('Show All') self._thumbnail_hide_action = submenu.addAction('Hide All') submenu.addSeparator() for topic, renderer in self._renderers: self._thumbnail_actions.append(submenu.addAction(topic)) self._thumbnail_actions[-1].setCheckable(True) self._thumbnail_actions[-1].setChecked(self.timeline._timeline_frame.is_renderer_active(topic)) else: self._thumbnail_show_action = None self._thumbnail_hide_action = None for topic, renderer in self._renderers: if menu_topic == topic: self._thumbnail_actions.append(self.addAction("Thumbnail")) self._thumbnail_actions[-1].setCheckable(True) self._thumbnail_actions[-1].setChecked(self.timeline._timeline_frame.is_renderer_active(topic)) # create view menu items self._topic_actions = [] self._type_actions = [] if menu_topic is None: self._topics = self.timeline._timeline_frame.topics view_topics_menu = self.addMenu('View (by Topic)') for topic in self._topics: datatype = self.timeline.get_datatype(topic) # View... / topic topic_menu = QMenu(topic, self) viewer_types = self.timeline._timeline_frame.get_viewer_types(datatype) # View... / topic / Viewer for viewer_type in viewer_types: tempaction = topic_menu.addAction(viewer_type.name) tempaction.setData(viewer_type) self._topic_actions.append(tempaction) view_topics_menu.addMenu(topic_menu) view_type_menu = self.addMenu('View (by Type)') self._topics_by_type = self.timeline._timeline_frame._topics_by_datatype for datatype in self._topics_by_type: # View... / datatype datatype_menu = QMenu(datatype, self) datatype_topics = self._topics_by_type[datatype] viewer_types = self.timeline._timeline_frame.get_viewer_types(datatype) for topic in [t for t in self._topics if t in datatype_topics]: # use timeline ordering topic_menu = QMenu(topic, datatype_menu) # View... / datatype / topic / Viewer for viewer_type in viewer_types: tempaction = topic_menu.addAction(viewer_type.name) tempaction.setData(viewer_type) self._topic_actions.append(tempaction) datatype_menu.addMenu(topic_menu) view_type_menu.addMenu(datatype_menu) else: view_menu = self.addMenu("View") datatype = self.timeline.get_datatype(menu_topic) viewer_types = self.timeline._timeline_frame.get_viewer_types(datatype) for viewer_type in viewer_types: tempaction = view_menu.addAction(viewer_type.name) tempaction.setData(viewer_type) self._topic_actions.append(tempaction) self.addSeparator() # create publish menu items self._publish_actions = [] if menu_topic is None: submenu = self.addMenu('Publish...') self._publish_all = submenu.addAction('Publish All') self._publish_none = submenu.addAction('Publish None') submenu.addSeparator() for topic in self._topics: self._publish_actions.append(submenu.addAction(topic)) self._publish_actions[-1].setCheckable(True) self._publish_actions[-1].setChecked(self.timeline.is_publishing(topic)) else: self._publish_actions.append(self.addAction("Publish")) self._publish_actions[-1].setCheckable(True) self._publish_actions[-1].setChecked(self.timeline.is_publishing(menu_topic)) self._publish_all = None self._publish_none = None action = self.exec_(event.globalPos()) if action is not None and action != 0: self.process(action)
class Plot3DWidget(QWidget): _redraw_interval = 40 def __init__(self, initial_topics=None, start_paused=False, buffer_length=100, use_poly=True, no_legend=False): super(Plot3DWidget, self).__init__() self.setObjectName('Plot3DWidget') self._buffer_length = buffer_length self._initial_topics = initial_topics rp = rospkg.RosPack() ui_file = os.path.join(rp.get_path('jsk_rqt_plugins'), 'resource', 'plot3d.ui') loadUi(ui_file, self) self.subscribe_topic_button.setIcon(QIcon.fromTheme('add')) self.remove_topic_button.setIcon(QIcon.fromTheme('remove')) self.pause_button.setIcon(QIcon.fromTheme('media-playback-pause')) self.clear_button.setIcon(QIcon.fromTheme('edit-clear')) self.data_plot = MatDataPlot3D(self, self._buffer_length, use_poly, no_legend) self.data_plot_layout.addWidget(self.data_plot) self.data_plot.autoscroll(self.autoscroll_checkbox.isChecked()) self.data_plot.dropEvent = self.dropEvent self.data_plot.dragEnterEvent = self.dragEnterEvent self.subscribe_topic_button.setEnabled(False) if start_paused: self.pause_button.setChecked(True) self._topic_completer = TopicCompleter(self.topic_edit) self._topic_completer.update_topics() self.topic_edit.setCompleter(self._topic_completer) self._start_time = rospy.get_time() self._rosdata = {} self._remove_topic_menu = QMenu() # init and start update timer for plot self._update_plot_timer = QTimer(self) self._update_plot_timer.timeout.connect(self.update_plot) if self._initial_topics: for topic_name in self._initial_topics: self.add_topic(topic_name) self._initial_topics = None @Slot('QDragEnterEvent*') def dragEnterEvent(self, event): # get topic name if not event.mimeData().hasText(): if not hasattr(event.source(), 'selectedItems') or len(event.source().selectedItems()) == 0: qWarning('Plot.dragEnterEvent(): not hasattr(event.source(), selectedItems) or len(event.source().selectedItems()) == 0') return item = event.source().selectedItems()[0] topic_name = item.data(0, Qt.UserRole) if topic_name == None: qWarning('Plot.dragEnterEvent(): not hasattr(item, ros_topic_name_)') return else: topic_name = str(event.mimeData().text()) # check for numeric field type is_numeric, is_array, message = is_slot_numeric(topic_name) if is_numeric and not is_array: event.acceptProposedAction() else: qWarning('Plot.dragEnterEvent(): rejecting: "%s"' % (message)) @Slot('QDropEvent*') def dropEvent(self, event): if event.mimeData().hasText(): topic_name = str(event.mimeData().text()) else: droped_item = event.source().selectedItems()[0] topic_name = str(droped_item.data(0, Qt.UserRole)) self.add_topic(topic_name) @Slot(str) def on_topic_edit_textChanged(self, topic_name): # on empty topic name, update topics if topic_name in ('', '/'): self._topic_completer.update_topics() is_numeric, is_array, message = is_slot_numeric(topic_name) self.subscribe_topic_button.setEnabled(is_numeric and not is_array) self.subscribe_topic_button.setToolTip(message) @Slot() def on_topic_edit_returnPressed(self): if self.subscribe_topic_button.isEnabled(): self.add_topic(str(self.topic_edit.text())) @Slot() def on_subscribe_topic_button_clicked(self): self.add_topic(str(self.topic_edit.text())) @Slot(bool) def on_pause_button_clicked(self, checked): self.enable_timer(not checked) @Slot(bool) def on_autoscroll_checkbox_clicked(self, checked): self.data_plot.autoscroll(checked) @Slot() def on_clear_button_clicked(self): self.clean_up_subscribers() def update_plot(self): if self.data_plot is not None: needs_redraw = False for topic_name, rosdata in self._rosdata.items(): try: data_x, data_y = rosdata.next() if data_x or data_y: self.data_plot.update_values(topic_name, data_x, data_y) needs_redraw = True except RosPlotException as e: qWarning('PlotWidget.update_plot(): error in rosplot: %s' % e) if needs_redraw: self.data_plot.redraw() def _subscribed_topics_changed(self): self._update_remove_topic_menu() if not self.pause_button.isChecked(): # if pause button is not pressed, enable timer based on subscribed topics self.enable_timer(self._rosdata) def _update_remove_topic_menu(self): def make_remove_topic_function(x): return lambda: self.remove_topic(x) self._remove_topic_menu.clear() for topic_name in sorted(self._rosdata.keys()): action = QAction(topic_name, self._remove_topic_menu) action.triggered.connect(make_remove_topic_function(topic_name)) self._remove_topic_menu.addAction(action) self.remove_topic_button.setMenu(self._remove_topic_menu) def add_topic(self, topic_name): if topic_name in self._rosdata: qWarning('PlotWidget.add_topic(): topic already subscribed: %s' % topic_name) return self._rosdata[topic_name] = ROSData(topic_name, self._start_time) if self._rosdata[topic_name].error is not None: qWarning(str(self._rosdata[topic_name].error)) del self._rosdata[topic_name] else: data_x, data_y = self._rosdata[topic_name].next() self.data_plot.add_curve(topic_name, topic_name, data_x, data_y) self._subscribed_topics_changed() def remove_topic(self, topic_name): self._rosdata[topic_name].close() del self._rosdata[topic_name] self.data_plot.remove_curve(topic_name) self._subscribed_topics_changed() def clean_up_subscribers(self): for topic_name, rosdata in self._rosdata.items(): rosdata.close() self.data_plot.remove_curve(topic_name) self._rosdata = {} self._subscribed_topics_changed() def enable_timer(self, enabled=True): if enabled: self._update_plot_timer.start(self._redraw_interval) else: self._update_plot_timer.stop()
def _create_tag_menu(self, parent=None): # creates a tag menu tag_menu = QMenu("ROS Tags", parent) # group tag add_group_tag_action = QAction("<group>", self, statusTip="", triggered=self._on_add_group_tag) add_group_tag_action.setShortcuts(QKeySequence("Ctrl+Shift+g")) tag_menu.addAction(add_group_tag_action) # node tag add_node_tag_action = QAction("<node>", self, statusTip="", triggered=self._on_add_node_tag) add_node_tag_action.setShortcuts(QKeySequence("Ctrl+Shift+n")) tag_menu.addAction(add_node_tag_action) # node tag with all attributes add_node_tag_all_action = QAction("<node all>", self, statusTip="", triggered=self._on_add_node_tag_all) tag_menu.addAction(add_node_tag_all_action) # include tag with all attributes add_include_tag_all_action = QAction("<include>", self, statusTip="", triggered=self._on_add_include_tag_all) add_include_tag_all_action.setShortcuts(QKeySequence("Ctrl+Shift+i")) tag_menu.addAction(add_include_tag_all_action) # remap add_remap_tag_action = QAction("<remap>", self, statusTip="", triggered=self._on_add_remap_tag) add_remap_tag_action.setShortcuts(QKeySequence("Ctrl+Shift+r")) tag_menu.addAction(add_remap_tag_action) # env tag add_env_tag_action = QAction("<env>", self, statusTip="", triggered=self._on_add_env_tag) tag_menu.addAction(add_env_tag_action) # param tag add_param_tag_action = QAction("<param>", self, statusTip="", triggered=self._on_add_param_tag) add_param_tag_action.setShortcuts(QKeySequence("Ctrl+Shift+p")) tag_menu.addAction(add_param_tag_action) # param capability group tag add_param_cap_group_tag_action = QAction("<param capability group>", self, statusTip="", triggered=self._on_add_param_cap_group_tag) add_param_cap_group_tag_action.setShortcuts(QKeySequence("Ctrl+Alt+p")) tag_menu.addAction(add_param_cap_group_tag_action) # param tag with all attributes add_param_tag_all_action = QAction("<param all>", self, statusTip="", triggered=self._on_add_param_tag_all) tag_menu.addAction(add_param_tag_all_action) # rosparam tag with all attributes add_rosparam_tag_all_action = QAction("<rosparam>", self, statusTip="", triggered=self._on_add_rosparam_tag_all) tag_menu.addAction(add_rosparam_tag_all_action) # arg tag with default definition add_arg_tag_default_action = QAction("<arg default>", self, statusTip="", triggered=self._on_add_arg_tag_default) add_arg_tag_default_action.setShortcuts(QKeySequence("Ctrl+Shift+a")) tag_menu.addAction(add_arg_tag_default_action) # arg tag with value definition add_arg_tag_value_action = QAction("<arg value>", self, statusTip="", triggered=self._on_add_arg_tag_value) add_arg_tag_value_action.setShortcuts(QKeySequence("Ctrl+Alt+a")) tag_menu.addAction(add_arg_tag_value_action) # test tag add_test_tag_action = QAction("<test>", self, statusTip="", triggered=self._on_add_test_tag) add_test_tag_action.setShortcuts(QKeySequence("Ctrl+Alt+t")) tag_menu.addAction(add_test_tag_action) # test tag with all attributes add_test_tag_all_action = QAction("<test all>", self, statusTip="", triggered=self._on_add_test_tag_all) tag_menu.addAction(add_test_tag_all_action) return tag_menu