37 from python_qt_binding.QtCore
import QMargins, QSize, Qt, Signal
38 from python_qt_binding.QtGui
import QFont, QIcon
39 from python_qt_binding.QtWidgets
import (QFormLayout, QGroupBox,
40 QHBoxLayout, QLabel, QPushButton,
41 QTabWidget, QVBoxLayout, QWidget)
46 from .param_editors
import (
47 BooleanEditor, DoubleEditor, EDITOR_TYPES, EditorWidget, EnumEditor,
48 IntegerEditor, StringEditor
53 'collapse':
'CollapseGroup',
56 'apply':
'ApplyGroup',
62 (Ze'ev) reaaaaallly cryptic function which returns the config object for 66 for k, v
in config.items():
68 if k.lower() == name.lower():
76 except Exception
as exc:
78 except AttributeError:
80 except Exception
as exc:
87 (Isaac's guess as of 12/13/2012) 88 This class bonds multiple Editor instances that are associated with 89 a single node as a group. 93 sig_node_disabled_selected = Signal(str)
94 sig_node_state_change = Signal(bool)
99 :type config: Dictionary? defined in dynamic_reconfigure.client.Client 112 verticalLayout = QVBoxLayout(self)
113 verticalLayout.setContentsMargins(QMargins(0, 0, 0, 0))
115 _widget_nodeheader = QWidget()
116 _h_layout_nodeheader = QHBoxLayout(_widget_nodeheader)
117 _h_layout_nodeheader.setContentsMargins(QMargins(0, 0, 0, 0))
120 font = QFont(
'Trebuchet MS, Bold')
121 font.setUnderline(
True)
125 _icon_disable_node = QIcon.fromTheme(
'window-close')
126 _bt_disable_node = QPushButton(_icon_disable_node,
'', self)
127 _bt_disable_node.setToolTip(
'Hide this node')
128 _bt_disable_node_size = QSize(36, 24)
129 _bt_disable_node.setFixedSize(_bt_disable_node_size)
133 _h_layout_nodeheader.addWidget(_bt_disable_node)
135 self.nodename_qlabel.setAlignment(Qt.AlignCenter)
136 font.setPointSize(10)
137 self.nodename_qlabel.setFont(font)
138 grid_widget = QWidget(self)
139 self.
grid = QFormLayout(grid_widget)
140 verticalLayout.addWidget(_widget_nodeheader)
141 verticalLayout.addWidget(grid_widget, 1)
154 logging.debug(
'Groups node name={}'.format(nodename))
155 self.nodename_qlabel.setText(nodename)
169 for param
in config[
'parameters']:
170 begin = time.time() * 1000
171 editor_type =
'(none)' 173 if param[
'edit_method']:
174 widget = EnumEditor(self.updater, param)
175 elif param[
'type']
in EDITOR_TYPES:
176 logging.debug(
'GroupWidget i_debug=%d param type =%s',
177 i_debug, param[
'type'])
178 editor_type = EDITOR_TYPES[param[
'type']]
179 widget = eval(editor_type)(self.updater, param)
181 self.editor_widgets.append(widget)
182 self._param_names.append(param[
'name'])
185 'groups._create_node_widgets num editors=%d', i_debug)
187 end = time.time() * 1000
188 time_elap = end - begin
189 logging.debug(
'ParamG editor={} loop=#{} Time={}msec'.format(
190 editor_type, i_debug, time_elap))
193 for name, group
in config[
'groups'].items():
194 if group[
'type'] ==
'tab':
196 self, self.updater, group, self._toplevel_treenode_name)
197 elif group[
'type']
in _GROUP_TYPES.keys():
198 widget = eval(_GROUP_TYPES[group[
'type']])(
199 self.updater, group, self._toplevel_treenode_name)
201 widget = eval(_GROUP_TYPES[
''])(
202 self.updater, group, self._toplevel_treenode_name)
204 self.editor_widgets.append(widget)
205 logging.debug(
'groups._create_node_widgets name=%s', name)
207 for i, ed
in enumerate(self.editor_widgets):
208 ed.display(self.grid)
210 logging.debug(
'GroupWdgt._create_node_widgets len(editor_widgets)=%d',
211 len(self.editor_widgets))
217 if 'state' in config:
218 old_state = self.
state 219 self.
state = config[
'state']
220 if self.
state != old_state:
221 self.sig_node_state_change.emit(self.
state)
223 names = [name
for name
in config.keys()]
226 if isinstance(widget, EditorWidget):
227 if widget.param_name
in names:
228 widget.update_value(config[widget.param_name])
229 elif isinstance(widget, GroupWidget):
230 cfg =
find_cfg(config, widget.param_name)
231 widget.update_group(cfg)
244 logging.debug(
'param_gs _node_disable_bt_clicked')
251 super(BoxGroup, self).
__init__(updater, config, nodename)
254 self.box.setLayout(self.
grid)
257 grid.addRow(self.
box)
263 super(CollapseGroup, self).
__init__(updater, config, nodename)
264 self.box.setCheckable(
True)
265 self.box.clicked.connect(self.
click_cb)
266 self.sig_node_state_change.connect(self.box.setChecked)
268 for child
in self.box.children():
269 if child.isWidgetType():
270 self.box.toggled.connect(child.setVisible)
272 self.box.setChecked(self.
state)
275 self.updater.update({
'groups': {self.
param_name: on}})
281 super(HideGroup, self).
__init__(updater, config, nodename)
282 self.box.setVisible(self.
state)
283 self.sig_node_state_change.connect(self.box.setVisible)
288 def __init__(self, parent, updater, config, nodename):
289 super(TabGroup, self).
__init__(updater, config, nodename)
292 if not self.parent.tab_bar:
293 self.parent.tab_bar = QTabWidget()
296 self.wid.setLayout(self.
grid)
301 if not self.parent.tab_bar_shown:
302 grid.addRow(self.parent.tab_bar)
303 self.parent.tab_bar_shown =
True 306 super(TabGroup, self).
close()
307 self.parent.tab_bar =
None 308 self.parent.tab_bar_shown =
False 320 for name, value
in config.items():
333 self.button.clicked.connect(self.updater.apply_update)
335 self.grid.addRow(self.
button)