diff --git a/src/pymodaq_gui/examples/parameter_ex.py b/src/pymodaq_gui/examples/parameter_ex.py index 6bd97576..1e977092 100644 --- a/src/pymodaq_gui/examples/parameter_ex.py +++ b/src/pymodaq_gui/examples/parameter_ex.py @@ -17,6 +17,11 @@ class ParameterEx(ParameterManager): {'title': 'A visible group:', 'name': 'agroup', 'type': 'group', 'children': []}, {'title': 'An hidden group:', 'name': 'bgroup', 'type': 'group', 'children': [], 'visible': False}, # this # visible option is not available in usual pyqtgraph group + {'title': 'A bool with children:', 'name': 'booleans_group', 'type': 'bool', 'value':False, 'tip': 'Any Parameter can have its own children', 'children': [ + {'title': 'A bool in a bool', 'name': 'a_bool_in_a_bool', 'type': 'bool', 'value': True}, + {'title': 'A push with children', 'name': 'aboolpush', 'type': 'bool_push', 'value': True, 'label': 'action','children':[ + {'title': 'A string in a group', 'name': 'atte_in_a_group', 'type': 'str', 'value': 'this is a string you can edit'}, + ]},]}, ]}, {'title': 'Numbers:', 'name': 'numbers', 'type': 'group', 'children': [ diff --git a/src/pymodaq_gui/parameter/ioxml.py b/src/pymodaq_gui/parameter/ioxml.py index d7f7e333..6150cdfe 100644 --- a/src/pymodaq_gui/parameter/ioxml.py +++ b/src/pymodaq_gui/parameter/ioxml.py @@ -41,22 +41,20 @@ def walk_parameters_to_xml(parent_elt=None, param=None): if parent_elt is None: opts = dict_from_param(param) parent_elt = ET.Element(param.name(), **opts) - param_type = str(param.type()) - if 'group' not in param_type: # covers 'group', custom 'groupmove', 'groupai' ... + if 'value' in param.opts: add_text_to_elt(parent_elt, param) params_list = param.children() for param in params_list: - opts = dict_from_param(param) elt = ET.Element(param.name(), **opts) - param_type = str(param.type()) - if 'group' not in param_type: # covers 'group', custom 'groupmove'... - add_text_to_elt(elt, param) - else: + if param.hasChildren(): walk_parameters_to_xml(elt, param) + if 'value' in param.opts: + add_text_to_elt(elt, param) parent_elt.append(elt) + return parent_elt @@ -193,6 +191,10 @@ def dict_from_param(param): movelist = str(param.opts['movelist']) opts.update(dict(movelist=movelist)) + if 'label' in param.opts: + label = str(param.opts['label']) + opts.update(dict(label=label)) + if 'show_pb' in param.opts: if param.opts['show_pb']: show_pb = '1' @@ -278,6 +280,10 @@ def elt_to_dict(el): addText = str(el.get('addText')) param.update(dict(addText=addText)) + if 'label' in el.attrib.keys(): + label = str(el.get('label')) + param.update(dict(label=label)) + # if 'limits' in el.attrib.keys(): # try: # values = list(eval(el.get('limits'))) # make sure the evaluated values are returned as list (in case another @@ -389,37 +395,35 @@ def walk_xml_to_parameter(params=[], XML_elt=None): raise TypeError('not valid XML element') if len(XML_elt) == 0: - param_dict = elt_to_dict(XML_elt) - param_type = XML_elt.get('type') - - if 'group' not in param_type: # covers 'group', custom 'groupmove'... - set_txt_from_elt(XML_elt, param_dict) + param_dict = set_dict_from_el(XML_elt) params.append(param_dict) for el in XML_elt: - param_dict = elt_to_dict(el) - param_type = el.get('type') - - if 'group' not in param_type: # covers 'group', custom 'groupmove'... - set_txt_from_elt(el, param_dict) + param_dict = set_dict_from_el(el) + if param_dict['type'] not in PARAM_TYPES: + param_dict['type'] = 'group' # in case the custom group has been defined somewhere but not + # registered again in this session + if len(el) == 0: + children = [] else: - if param_type not in PARAM_TYPES: - param_dict['type'] = 'group' # in case the custom group has been defined somewhere but not - # registered again in this session - if len(el) == 0: - children = [] - else: - subparams = [] - children = walk_xml_to_parameter(subparams, el) - param_dict['children'] = children - - param_dict['name'] = el.tag - + subparams = [] + children = walk_xml_to_parameter(subparams, el) + param_dict['children'] = children params.append(param_dict) + except Exception as e: # to be able to debug when there's an issue raise e return params +def set_dict_from_el(el): + """Convert an element into a dict + ---------- + el: xml element + param_dict: dictionnary from which the parameter will be constructed + """ + param_dict = elt_to_dict(el) + set_txt_from_elt(el, param_dict) + return param_dict def set_txt_from_elt(el, param_dict): """ @@ -431,7 +435,8 @@ def set_txt_from_elt(el, param_dict): """ val_text = el.text - param_type = el.get('type') + param_type = param_dict['type'] + # param_type = el.get('type') # Redundancy (param_dict already has this attribute) if val_text is not None: if param_type == 'float': param_value = float(val_text) diff --git a/src/pymodaq_gui/parameter/utils.py b/src/pymodaq_gui/parameter/utils.py index 881fe648..2f5c08f5 100644 --- a/src/pymodaq_gui/parameter/utils.py +++ b/src/pymodaq_gui/parameter/utils.py @@ -143,37 +143,61 @@ def compareValuesParameter(param1:Parameter,param2:Parameter,)-> bool: """ return getValues(param1) == getValues(param2) -def iter_children(param, childlist=[]): - """Get a list of parameters name under a given Parameter - | Returns all childrens names. +def iter_children(param, childlist=[], filter_type=(), filter_name=(), select_filter=False)-> list: - =============== ================================= ==================================== - **Parameters** **Type** **Description** - *param* instance of pyqtgraph parameter the root node to be coursed - *childlist* list the child list recetion structure - =============== ================================= ==================================== + """ + Get a list of parameters' name under a given Parameter (see iter_children_params) - Returns - ------- - childlist : parameter list - The list of the children from the given node. + Returns + ------- + list + The list of the children name from the given node. """ - for child in param.children(): - childlist.append(child.name()) - if child.hasChildren(): - # if 'group' in child.type(): - childlist.extend(iter_children(child, [])) - return childlist + return iter_children_params(param, childlist=childlist, output_type='name', filter_type=(), filter_name=(), select_filter=False) -def iter_children_params(param, childlist=[]): - """Get a list of parameters under a given Parameter +def iter_children_params(param, childlist=[], output_type=None, filter_type=(), filter_name=(), select_filter=False)-> list: + """ + Get a list of parameters under a given Parameter. + + Parameters + ---------- + param : Parameter (pyqtgraph) + the root node to be coursed + childlist: list + the child/output list + output_type: str + the attribute of parameter that will be added to the output list + filter_type: list + filter children sharing those types + filter_name: list + filter children sharing those names + select_filter: bool + if True, add filtered parameters to output list. + if False (default), add non-filtered parameter to output list. + Returns + ------- + list + The list of the children from the given node. """ + for child in param.children(): - childlist.append(child) + # XNOR Gate + is_filtered = child.type() in filter_type or child.name() in filter_name + add_selected_child = select_filter and is_filtered + add_notselected_child = not select_filter and not is_filtered + if add_selected_child or add_notselected_child: + if output_type is not None: + try: + output = getattr(child,output_type)() + except Exception as e: + print(str(e)) + else: + output = child + childlist.append(output) if child.hasChildren(): - childlist.extend(iter_children_params(child, [])) + childlist.extend(iter_children_params(child, [], output_type, filter_type, filter_name, select_filter)) return childlist diff --git a/tests/managers/parameter_manager_test.py b/tests/managers/parameter_manager_test.py index cd330336..79d6a5cf 100644 --- a/tests/managers/parameter_manager_test.py +++ b/tests/managers/parameter_manager_test.py @@ -11,7 +11,7 @@ from pyqtgraph.parametertree import Parameter from pymodaq_gui.examples.parameter_ex import ParameterEx -from pymodaq_gui.parameter.utils import ( +from pymodaq_gui.parameter.utils import (getValues,getStruct, iter_children_params, compareParameters, compareStructureParameter, compareValuesParameter) from pymodaq_gui.utils.widgets.table import TableModel @@ -69,7 +69,7 @@ def test_load(qtbot, tmp_path): ptree.save_settings_slot(file_path) parameter_copy = Parameter.create(name='settings', type='group', children=ParameterEx.params) - compareValuesParameter(ptree.settings, parameter_copy) + assert compareValuesParameter(ptree.settings, parameter_copy) parameters = iter_children_params(ptree.settings, childlist=[]) parameters_copy = iter_children_params(parameter_copy, childlist=[]) diff --git a/tests/parameter_test/param_ioxml_test.py b/tests/parameter_test/param_ioxml_test.py index 1af240b6..6dcadfc2 100644 --- a/tests/parameter_test/param_ioxml_test.py +++ b/tests/parameter_test/param_ioxml_test.py @@ -99,9 +99,9 @@ class TestXMLbackForth(): def test_save_load_xml(self): param_back = ioxml.XML_string_to_pobject(ioxml.parameter_to_xml_string(self.settings)) - - for child, child_back in zip(putils.iter_children_params(self.settings), - putils.iter_children_params(param_back)): + children_list_in = putils.iter_children_params(self.settings) + children_list_back = putils.iter_children_params(param_back) + for child, child_back in zip(children_list_in,children_list_back): assert child_back.name() == child.name() assert child_back.title() == child.title() assert child_back.value() == child.value() diff --git a/tests/parameter_test/param_utils_test.py b/tests/parameter_test/param_utils_test.py index 73eacbb4..b36d26aa 100644 --- a/tests/parameter_test/param_utils_test.py +++ b/tests/parameter_test/param_utils_test.py @@ -58,6 +58,27 @@ P3 = Parameter(name='settings3', type='group', children=params3) P4 = Parameter(name='settings4', type='group', children=params4) +def test_iter_children_params(): + settings = Parameter.create(name='settings', type='group', children=params) + param_list = putils.iter_children_params(settings,childlist=[],filter_type=['group']) + assert all([p.type() != 'group' for p in param_list]) + param_list = putils.iter_children_params(settings,childlist=[],filter_name=['axis']) + assert all([p.name() != 'axis' for p in param_list]) + param_list = putils.iter_children_params(settings,childlist=[],filter_name=['axis'],select_filter=True) + assert all([p.name() == 'axis' for p in param_list]) + param_list = putils.iter_children_params(settings,childlist=[],filter_type=['group'],select_filter=True) + assert all([p.type() == 'group' for p in param_list]) + +def test_iter_children_attributes(): + settings = Parameter.create(name='settings', type='group', children=params) + param_name = putils.iter_children_params(settings, childlist=[], output_type='name') + param_type = putils.iter_children_params(settings, childlist=[], output_type='type') + param_list = putils.iter_children_params(settings, childlist=[]) + for p_name,p_type,p in zip(param_name,param_type,param_list): + assert p_name == p.name() + assert p_type == p.type() + + def test_get_param_path(): settings = Parameter.create(name='settings', type='group', children=params)