paramedit_widget.py
Go to the documentation of this file.
00001 # Software License Agreement (BSD License)
00002 #
00003 # Copyright (c) 2012, Willow Garage, Inc.
00004 # All rights reserved.
00005 #
00006 # Redistribution and use in source and binary forms, with or without
00007 # modification, are permitted provided that the following conditions
00008 # are met:
00009 #
00010 #  * Redistributions of source code must retain the above copyright
00011 #    notice, this list of conditions and the following disclaimer.
00012 #  * Redistributions in binary form must reproduce the above
00013 #    copyright notice, this list of conditions and the following
00014 #    disclaimer in the documentation and/or other materials provided
00015 #    with the distribution.
00016 #  * Neither the name of Willow Garage, Inc. nor the names of its
00017 #    contributors may be used to endorse or promote products derived
00018 #    from this software without specific prior written permission.
00019 #
00020 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00030 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031 # POSSIBILITY OF SUCH DAMAGE.
00032 #
00033 # Author: Isaac Saito, Ze'ev Klapow
00034 
00035 import os
00036 from collections import OrderedDict
00037 
00038 import dynamic_reconfigure.client
00039 from python_qt_binding import loadUi
00040 from python_qt_binding.QtCore import Qt, Signal
00041 from python_qt_binding.QtWidgets import QVBoxLayout, QWidget, QWidgetItem
00042 from rqt_py_common.layout_util import LayoutUtil
00043 import rospy
00044 
00045 from . import logging
00046 from .dynreconf_client_widget import DynreconfClientWidget
00047 
00048 
00049 class ParameditWidget(QWidget):
00050     """
00051     This class represents a pane where parameter editor widgets of multiple
00052     nodes are shown. In rqt_reconfigure, this pane occupies right half of the
00053     entire visible area.
00054     """
00055 
00056     # public signal
00057     sig_node_disabled_selected = Signal(str)
00058 
00059     def __init__(self, rospack):
00060         """"""
00061         super(ParameditWidget, self).__init__()
00062 
00063         ui_file = os.path.join(rospack.get_path('rqt_reconfigure'),
00064                                'resource', 'paramedit_pane.ui')
00065         loadUi(ui_file, self, {'ParameditWidget': ParameditWidget})
00066 
00067         self._dynreconf_clients = OrderedDict()
00068 
00069         # Adding the list of Items
00070         self.vlayout = QVBoxLayout(self.scrollarea_holder_widget)
00071 
00072         #self._set_index_widgets(self.listview, paramitems_dict) # causes error
00073         self.destroyed.connect(self.close)
00074 
00075     def _set_index_widgets(self, view, paramitems_dict):
00076         """
00077         @deprecated: Causes error
00078         """
00079         i = 0
00080         for p in paramitems_dict:
00081             view.setIndexWidget(i, p)
00082             i += 1
00083 
00084     def show_reconf(self, dynreconf_widget):
00085         """
00086         Callback when user chooses a node.
00087 
00088         @param dynreconf_widget:
00089         """
00090         node_grn = dynreconf_widget.get_node_grn()
00091         logging.debug('ParameditWidget.show str(node_grn)=%s', str(node_grn))
00092 
00093         if not node_grn in self._dynreconf_clients.keys():
00094             # Add dynreconf widget if there isn't already one.
00095 
00096             # Client gets renewed every time different node_grn was clicked.
00097 
00098             self._dynreconf_clients.__setitem__(node_grn, dynreconf_widget)
00099             self.vlayout.addWidget(dynreconf_widget)
00100             dynreconf_widget.sig_node_disabled_selected.connect(
00101                                                            self._node_disabled)
00102 
00103         else:  # If there has one already existed, remove it.
00104             self._remove_node(node_grn)
00105             #LayoutUtil.clear_layout(self.vlayout)
00106 
00107             # Re-add the rest of existing items to layout.
00108             #for k, v in self._dynreconf_clients.items():
00109             #    logging.info('added to layout k={} v={}'.format(k, v))
00110             #    self.vlayout.addWidget(v)
00111 
00112         # Add color to alternate the rim of the widget.
00113         LayoutUtil.alternate_color(
00114             self._dynreconf_clients.values(),
00115             [self.palette().window().color().lighter(125),
00116              self.palette().window().color().darker(125)])
00117 
00118     def close(self):
00119         for dc in self._dynreconf_clients:
00120             # Clear out the old widget
00121             dc.close()
00122             dc = None
00123 
00124             self._paramedit_scrollarea.deleteLater()
00125 
00126     def filter_param(self, filter_key):
00127         """
00128         :type filter_key:
00129         """
00130 
00131         #TODO Pick nodes that match filter_key.
00132 
00133         #TODO For the nodes that are kept in previous step, call
00134         #     DynreconfWidget.filter_param for all of its existing
00135         #     instances.
00136         pass
00137 
00138     def _remove_node(self, node_grn):
00139         try:
00140             i = self._dynreconf_clients.keys().index(node_grn)
00141         except ValueError:
00142             # ValueError occurring here means that the specified key is not
00143             # found, most likely already removed, which is possible in the
00144             # following situation/sequence:
00145             #
00146             # Node widget on ParameditWidget removed by clicking disable button
00147             # --> Node deselected on tree widget gets updated
00148             # --> Tree widget detects deselection
00149             # --> Tree widget emits deselection signal, which is captured by
00150             #     ParameditWidget's slot. Thus reaches this method again.
00151             return
00152 
00153         item = self.vlayout.itemAt(i)
00154         if isinstance(item, QWidgetItem):
00155                 item.widget().close()
00156         w = self._dynreconf_clients.pop(node_grn)
00157 
00158         logging.debug('popped={} Len of left clients={}'.format(
00159                                             w, len(self._dynreconf_clients)))
00160 
00161     def _node_disabled(self, node_grn):
00162         logging.debug('paramedit_w _node_disabled grn={}'.format(node_grn))
00163 
00164         # Signal to notify other GUI components (eg. nodes tree pane) that
00165         # a node widget is disabled.
00166         self.sig_node_disabled_selected.emit(node_grn)
00167 
00168         # Remove the selected node widget from the internal list of nodes.
00169         self._remove_node(node_grn)


rqt_reconfigure
Author(s): Isaac Saito, Ze'ev Klapow
autogenerated on Sat Jul 6 2019 03:49:38