param_widget.py
Go to the documentation of this file.
1 # Software License Agreement (BSD License)
2 #
3 # Copyright (c) 2012, Willow Garage, Inc.
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 #
10 # * Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # * Redistributions in binary form must reproduce the above
13 # copyright notice, this list of conditions and the following
14 # disclaimer in the documentation and/or other materials provided
15 # with the distribution.
16 # * Neither the name of Willow Garage, Inc. nor the names of its
17 # contributors may be used to endorse or promote products derived
18 # from this software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 # POSSIBILITY OF SUCH DAMAGE.
32 #
33 # Author: Isaac Saito
34 
35 from __future__ import division
36 
37 import sys
38 
39 from python_qt_binding.QtCore import QMargins, Signal
40 from python_qt_binding.QtWidgets import (
41  QHBoxLayout, QLabel, QSplitter, QVBoxLayout, QWidget
42 )
43 
44 import rospkg
45 
46 import rospy
47 
48 from rqt_reconfigure import logging
49 from rqt_reconfigure.node_selector_widget import NodeSelectorWidget
50 from rqt_reconfigure.paramedit_widget import ParameditWidget
51 from rqt_reconfigure.text_filter import TextFilter
52 from rqt_reconfigure.text_filter_widget import TextFilterWidget
53 
54 
55 class ParamWidget(QWidget):
56  _TITLE_PLUGIN = 'Dynamic Reconfigure'
57 
58  # To be connected to PluginContainerWidget
59  sig_sysmsg = Signal(str)
60  sig_sysprogress = Signal(str)
61 
62  # To make selections from CLA
63  sig_selected = Signal(str)
64 
65  def __init__(self, context, node=None):
66  """
67  This class is intended to be called by rqt plugin framework class.
68  Currently (12/12/2012) the whole widget is splitted into 2 panes:
69  one on left allows you to choose the node(s) you work on. Right side
70  pane lets you work with the parameters associated with the node(s) you
71  select on the left.
72 
73  (12/27/2012) Despite the pkg name is changed to rqt_reconfigure to
74  reflect the available functionality, file & class names remain
75  'param', expecting all the parameters will become handle-able.
76  """
77  super(ParamWidget, self).__init__()
78  self.setObjectName(self._TITLE_PLUGIN)
79  self.setWindowTitle(self._TITLE_PLUGIN)
80 
81  rp = rospkg.RosPack()
82 
83  # TODO: .ui file needs to replace the GUI components declaration
84  # below. For unknown reason, referring to another .ui files
85  # from a .ui that is used in this class failed. So for now,
86  # I decided not use .ui in this class.
87  # If someone can tackle this I'd appreciate.
88  _hlayout_top = QHBoxLayout(self)
89  _hlayout_top.setContentsMargins(QMargins(0, 0, 0, 0))
90  self._splitter = QSplitter(self)
91  _hlayout_top.addWidget(self._splitter)
92 
93  _vlayout_nodesel_widget = QWidget()
94  _vlayout_nodesel_side = QVBoxLayout()
95  _hlayout_filter_widget = QWidget(self)
96  _hlayout_filter = QHBoxLayout()
99  self.filterkey_label = QLabel('&Filter key:')
100  self.filterkey_label.setBuddy(self.filter_lineedit)
101  _hlayout_filter.addWidget(self.filterkey_label)
102  _hlayout_filter.addWidget(self.filter_lineedit)
103  _hlayout_filter_widget.setLayout(_hlayout_filter)
105  self, rp, self.sig_sysmsg
106  )
107  _vlayout_nodesel_side.addWidget(_hlayout_filter_widget)
108  _vlayout_nodesel_side.addWidget(self._nodesel_widget)
109  _vlayout_nodesel_side.setSpacing(1)
110  _vlayout_nodesel_widget.setLayout(_vlayout_nodesel_side)
111 
112  reconf_widget = ParameditWidget(rp)
113 
114  self._splitter.insertWidget(0, _vlayout_nodesel_widget)
115  self._splitter.insertWidget(1, reconf_widget)
116  # 1st column, _vlayout_nodesel_widget, to minimize width.
117  # 2nd col to keep the possible max width.
118  self._splitter.setStretchFactor(0, 0)
119  self._splitter.setStretchFactor(1, 1)
120 
121  # Signal from paramedit widget to node selector widget.
122  reconf_widget.sig_node_disabled_selected.connect(
123  self._nodesel_widget.node_deselected
124  )
125  # Pass name of node to editor widget
126  self._nodesel_widget.sig_node_selected.connect(
127  reconf_widget.show_reconf
128  )
129 
130  if not node:
131  title = self._TITLE_PLUGIN
132  else:
133  title = self._TITLE_PLUGIN + ' %s' % node
134  self.setObjectName(title)
135 
136  # Connect filter signal-slots.
137  self._text_filter.filter_changed_signal.connect(
139  )
140 
141  # Open any clients indicated from command line
142  self.sig_selected.connect(self._nodesel_widget.node_selected)
143  for rn in [rospy.resolve_name(c) for c in context.argv()]:
144  if rn in self._nodesel_widget.get_paramitems():
145  self.sig_selected.emit(rn)
146  else:
147  logging.warn(
148  "Could not find a dynamic reconfigure client named '%s'",
149  str(rn)
150  )
151 
152  def shutdown(self):
153  # TODO: Needs implemented. Trigger dynamic_reconfigure to unlatch
154  # subscriber.
155  pass
156 
157  def save_settings(self, plugin_settings, instance_settings):
158  instance_settings.set_value('splitter', self._splitter.saveState())
159 
160  def restore_settings(self, plugin_settings, instance_settings):
161  if instance_settings.contains('splitter'):
162  self._splitter.restoreState(instance_settings.value('splitter'))
163  else:
164  self._splitter.setSizes([100, 100, 200])
165 
166  def get_filter_text(self):
167  """
168  :rtype: QString
169  """
170  return self.filter_lineedit.text()
171 
173  self._nodesel_widget.set_filter(self._text_filter)
174 
175  # TODO: This method should be integrated into common architecture. I just
176  # can't think of how to do so within current design.
177  def emit_sysmsg(self, msg_str):
178  self.sig_sysmsg.emit(msg_str)
179 
180 
181 if __name__ == '__main__':
182  # main should be used only for debug purpose.
183  # This launches this QWidget as a standalone rqt gui.
184  from rqt_gui.main import Main
185 
186  main = Main()
187  sys.exit(main.main(sys.argv, standalone='rqt_reconfigure'))
def restore_settings(self, plugin_settings, instance_settings)
def __init__(self, context, node=None)
Definition: param_widget.py:65
def save_settings(self, plugin_settings, instance_settings)


rqt_reconfigure
Author(s): Isaac Saito, Ze'ev Klapow
autogenerated on Wed Jul 10 2019 04:02:40