37 from python_qt_binding.QtCore
import (QEvent, QMargins, QObject, QSize, Qt,
39 from python_qt_binding.QtGui
import QFont, QIcon
40 from python_qt_binding.QtWidgets
import (QFormLayout, QGroupBox,
41 QHBoxLayout, QLabel, QPushButton,
42 QTabWidget, QVBoxLayout, QWidget)
44 from rqt_reconfigure
import logging
48 BooleanEditor, DoubleEditor, EDITOR_TYPES, EditorWidget, EnumEditor,
49 IntegerEditor, StringEditor
54 'collapse':
'CollapseGroup',
57 'apply':
'ApplyGroup',
63 (Ze'ev) reaaaaallly cryptic function which returns the config object for
67 for k, v
in config.items():
69 if k.lower() == name.lower():
77 except Exception
as exc:
79 except AttributeError:
81 except Exception
as exc:
88 (Isaac's guess as of 12/13/2012)
89 This class bonds multiple Editor instances that are associated with
90 a single node as a group.
94 sig_node_disabled_selected = Signal(str)
95 sig_node_state_change = Signal(bool)
100 :type config: Dictionary? defined in dynamic_reconfigure.client.Client
113 verticalLayout = QVBoxLayout(self)
114 verticalLayout.setContentsMargins(QMargins(0, 0, 0, 0))
116 _widget_nodeheader = QWidget()
117 _h_layout_nodeheader = QHBoxLayout(_widget_nodeheader)
118 _h_layout_nodeheader.setContentsMargins(QMargins(0, 0, 0, 0))
121 font = QFont(
'Trebuchet MS, Bold')
122 font.setUnderline(
True)
126 _icon_disable_node = QIcon.fromTheme(
'window-close')
127 _bt_disable_node = QPushButton(_icon_disable_node,
'', self)
128 _bt_disable_node.setToolTip(
'Hide this node')
129 _bt_disable_node_size = QSize(36, 24)
130 _bt_disable_node.setFixedSize(_bt_disable_node_size)
134 _h_layout_nodeheader.addWidget(_bt_disable_node)
137 font.setPointSize(10)
139 grid_widget = QWidget(self)
140 self.
grid = QFormLayout(grid_widget)
141 verticalLayout.addWidget(_widget_nodeheader)
142 verticalLayout.addWidget(grid_widget, 1)
155 logging.debug(
'Groups node name={}'.format(nodename))
170 for param
in config[
'parameters']:
171 begin = time.time() * 1000
172 editor_type =
'(none)'
174 if param[
'edit_method']:
175 widget = EnumEditor(self.updater, param)
176 elif param[
'type']
in EDITOR_TYPES:
177 logging.debug(
'GroupWidget i_debug={} param type ={}'.format(
178 i_debug, param[
'type']))
179 editor_type = EDITOR_TYPES[param[
'type']]
180 widget = eval(editor_type)(self.updater, param)
182 self.editor_widgets.append(widget)
183 self._param_names.append(param[
'name'])
186 'groups._create_node_widgets num editors={}'.format(i_debug))
188 end = time.time() * 1000
189 time_elap = end - begin
190 logging.debug(
'ParamG editor={} loop=#{} Time={}msec'.format(
191 editor_type, i_debug, time_elap))
194 for name, group
in sorted(config[
'groups'].items()):
195 if group[
'type'] ==
'tab':
197 self, self.updater, group, self._toplevel_treenode_name)
198 elif group[
'type']
in _GROUP_TYPES.keys():
199 widget = eval(_GROUP_TYPES[group[
'type']])(
200 self.updater, group, self._toplevel_treenode_name)
202 widget = eval(_GROUP_TYPES[
''])(
203 self.updater, group, self._toplevel_treenode_name)
205 self.editor_widgets.append(widget)
206 logging.debug(
'groups._create_node_widgets name={}'.format(name))
208 for i, ed
in enumerate(self.editor_widgets):
209 ed.display(self.grid)
211 logging.debug(
'GroupWdgt._create_node_widgets'
212 ' len(editor_widgets)={}'.format(
213 len(self.editor_widgets)))
221 if 'state' in config:
222 old_state = self.
state
223 self.
state = config[
'state']
224 if self.
state != old_state:
227 names = [name
for name
in config.keys()]
230 if isinstance(widget, EditorWidget):
231 if widget.param_name
in names:
232 widget.update_value(config[widget.param_name])
233 elif isinstance(widget, GroupWidget):
234 cfg =
find_cfg(config, widget.param_name)
or config
235 widget.update_group(cfg)
248 logging.debug(
'param_gs _node_disable_bt_clicked')
255 super(BoxGroup, self).
__init__(updater, config, nodename)
261 grid.addRow(self.
box)
267 super(CollapseGroup, self).
__init__(updater, config, nodename)
268 self.
box.setCheckable(
True)
272 for child
in self.
box.children():
273 if child.isWidgetType():
274 self.
box.toggled.connect(child.setVisible)
285 super(HideGroup, self).
__init__(updater, config, nodename)
292 def __init__(self, parent, updater, config, nodename):
293 super(TabGroup, self).
__init__(updater, config, nodename)
296 if not self.
parent.tab_bar:
297 self.
parent.tab_bar = QTabWidget()
300 self.
parent.tab_bar.tabBar().installEventFilter(self)
308 if event.type() == QEvent.Wheel
and not obj.hasFocus():
310 return super(GroupWidget, self).
eventFilter(obj, event)
313 if not self.
parent.tab_bar_shown:
314 grid.addRow(self.
parent.tab_bar)
315 self.
parent.tab_bar_shown =
True
318 super(TabGroup, self).
close()
319 self.
parent.tab_bar =
None
320 self.
parent.tab_bar_shown =
False
326 pending_updates = Signal(bool)
335 for name, value
in config.items():
352 self.
button.setEnabled(
False)
358 if not pending_updates
and self.
button.hasFocus():
362 self.
button.setEnabled(pending_updates)