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)
Exemple #2
0
    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)
Exemple #3
0
    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())
Exemple #5
0
    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
Exemple #9
0
 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 _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)
Exemple #15
0
 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')
Exemple #16
0
    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 _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 _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 _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 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())
Exemple #32
0
    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()
Exemple #35
0
    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()
Exemple #42
0
    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