Skip to content

Parameter with Python list

For most of the value types, the PythonPart parameter can be created as a Python list. The list can be one or two-dimensional. Below are some examples of simple lists with predefined lengths and items:

One dimensional list

<Parameter>
    <Name>CubeDimensions</Name>
    <Text> </Text>
    <Value>[1000.,1200.,1400.,1600.,1800.]</Value><!--(1)!-->
    <ValueType>Length</ValueType>
</Parameter>
  1. A list comprehension or any Python statement, which creates a list, will work here:

    • [1000.0 + x * 200.0 for x in range(5)]
    • [1000.] * 5

Two dimensional list

<Parameter>d
    <Name>Coordinates</Name>
    <Text>Coordinate</Text>
    <Value>[[0 for x in range(3)] for y in range(5)]</Value>
    <ValueType>Length</ValueType>
</Parameter>

Info

When a list consists of simple objects, like integer or string, you can use coma , as separator. However, for complex objects e.g., a list of points use the semicolon ; as separator:

<Parameter>
    <Name>PointList</Name>
    <Text></Text>
    <Value>[Point2D(0,500);Point2D(0,0);Point2D(400,20)]</Value>
    <ValueType>Point2D</ValueType>
</Parameter>

Access specific item(s)

Multi index control

Instead of displaying all the list items in the palette, you can provide the user an edit control for accessing specific list item(s) and one single control to modify this item. This makes the layout much more compact even in case of long lists. At the same time, it allows modification of multiple items by accessing them by index, like 1,3,5 or 1-5.

First add a special MultiIndex parameter for controlling the indices:

<Parameter>
    <Name>SizeIndex</Name>
    <Text>Cube index</Text>
    <Value>1</Value>
    <ValueType>MultiIndex</ValueType>
    <MinValue>1<!--(1)!--></MinValue>
    <MaxValue>5<!--(2)!--></MaxValue>
</Parameter>
  1. The lowest index, that can be accessed.
  2. The highest index, that can be accessed. Normally, the list length.

Then add the tag <ValueIndexName> to the list parameter, that should by accessed and provide the name of the MultiIndex parameter:

<Parameter>
    <Name>CubeSize</Name>
    <Text>Cube size</Text>
    <Value>[1000,1500,2000,2500,4000]</Value>
    <ValueType>Length</ValueType>
    <ValueIndexName>SizeIndex</ValueIndexName><!--(1)!-->
</Parameter>
  1. Of course you can provide here a fix value, a python formula or any other parameter, that returns an integer. It does not necessarily has to be a MultiIndex parameter.

Dynamic list

To allow the user to add or remove items to/from the list, you have a couple of possibilities. One of them is to provide an integer parameter controlling the length of the list and refer to it with the <Dimensions> tag. The second option is to define the parameter with DynamicList value type.

Dimensions tag

When a tag <Dimensions> is added to a list parameter, the length of the list will be controlled by another integer parameter, whose name is specified in the tag. This allows to append and remove items to/from the list.
Advantage: The user can append multiple items to the list by simply increasing the length of the list by any value.
Disadvantage: The user can remove only the last items from the list.

<Parameter>
    <Name>CubeDimensions</Name>
    <Text> </Text>
    <Value>[1000.,1200.,1400.,1600.,1800.]</Value>
    <ValueType>Length</ValueType>
    <Dimensions>CubeCount</Dimensions><!--(1)!-->
</Parameter>
  1. The tag can contain:

    • an integer constant <Dimensions>3</Dimensions>,
    • a name of an existing Integer parameter <Dimensions>CubeCount</Dimensions>,
    • a formula created by parameter names <Dimensions>CubeCount + 1</Dimensions>.
<Parameter>
    <Name>Coordinates</Name>
    <Text>Coordinate</Text>
    <Value>[[0 for x in range(3)] for y in range(5)]</Value>
    <ValueType>Length</ValueType>
    <Dimensions>CubeCount,CoordDimension3D + 2</Dimensions><!--(1)!-->
</Parameter>
  1. In this case two values separated with , must be provided

Dynamic list value type

Dynamic list

The list parameter can be created as a special DynamicList(...) value type. This type of parameter is very similar to the list parameter with MultiIndex, except the user can extend the list.
Advantage: The user can remove any of the list items. Disadvantage: The user can append only one item at the end of the list

To achieve this, first you have to define a MultiIndex parameter, exactly the same as for accessing items of a static list.

<Parameter>
    <Name>SphereRadiusIndex</Name>
    <Text>Sphere index</Text>
    <Value>1</Value>
    <ValueType>MultiIndex</ValueType>
    <MinValue>1</MinValue>
    <MaxValue>len(SphereRadius) + 1</MaxValue><!--(1)!-->
</Parameter>
  1. The maximum index must be the length of the list plus one. This allows to add an extra item.

Then, add the actual parameter with a <ValueType> set to DynamicList(...). Replace the ... with the desired type of the list items.

<Parameter>
    <Name>SphereRadius</Name>
    <Text>Sphere radius</Text>
    <Value>[_]</Value><!--(1)!-->
    <ValueType>DynamicList(Length)</ValueType>
    <ValueIndexName>RadiusIndex</ValueIndexName><!--(2)!-->
</Parameter>
  1. The list is initialized as empty list. Learn more about empty lists here
  2. The tag <ValueIndexName> is mandatory for DynamicList(...)!

Empty list

To initialize an empty list, use the square brackets with an underline [_], like this:

<Parameter>
    <Name>PointList</Name>
    <Text></Text>
    <Value>[_]</Value><!--(1)!-->
    <ValueType>Point2D</ValueType>
</Parameter>
  1. Initializing an empty list like this is important, when the list elements are objects like point or common properties. Initializing the list with [] would result in a list containing one (empty) object, e.g. [Point2D(0,0,0)].

    In case of python built-in objects like string or integer, it will make no difference.

To initialize a list containing a certain number of empty elements, like common properties or lines we can use the square brackets with an appropriate number of semicolons in it, like this:

<Parameter>
    <Name>PointList</Name>
    <Text></Text>
    <Value>[;;]</Value><!--(1)!-->
    <ValueType>Point2D</ValueType>
</Parameter>
  1. This will result in a python list consisting of 3 zero points

    [Point2D(0, 0), Point2D(0, 0), Point2D(0, 0)]
    

Optional tags

Initial row index

Each row of the list in the property palette is tagged with a row index. By default, the indexing starts at 0, but this can be changed by adding the tag <ValueListStartRow>.

<Parameter>
    <Name>Coordinates</Name>
    <Text>Coordinate</Text>
    <Value>[[0 for x in range(3)] for y in range(5)]</Value>
    <ValueType>Length</ValueType>
    <ValueListStartRow>-1<!--(1)!--></ValueListStartRow>
</Parameter>
  1. Setting the value to -1 will result in hiding the index completely. The result will look like this:

    Two dimensional list with no index

Accessing list item index

The special keyword $list_row allows access to the current list item index. The index starts with 0.

<Parameter>
    <Name>EnableVisibleItemsByListRow</Name>
    <Text></Text>
    <Value>[1000.,1200.,1400.,1600.,1800.,2000]</Value>
    <ValueType>Length</ValueType>
    <MinValue>100</MinValue>
    <Visible>$list_row != HideRowListRow</Visible>
    <Enable>$list_row != EnableRowListRow</Enable>
</Parameter>

Grouping

Individual parameter with value lists can be grouped to combine the controls with the same list item index into a block. This can be done by putting the list parameters into a ListGroup parameter. Here are short examples of how to group list parameters...

Group one dimensional list

<Parameter>
    <Name>ListGroup1</Name>
    <ValueType>ListGroup</ValueType>

    <Parameter>
        <Name>GroupExpander</Name>
        <Text>"Field " + str($list_row + 1)</Text>
        <ValueType>Expander</ValueType>

        <Parameter>
            <Name>SectionName</Name>
            <Text>Section name</Text>
            <Value>["A", "B", "C"]</Value>
            <ValueType>String</ValueType>
        </Parameter>

        <Parameter>
            <Name>Distance</Name>
            <Text>Distance</Text>
            <Value>[1000, 2000, 3000]</Value>
            <ValueType>Length</ValueType>
        </Parameter>

        <Parameter>
            <Name>GroupButtonRow</Name>
            <Text>"Group " + str($list_row + 1)</Text>
            <ValueType>Row</ValueType>
            <Parameter>
                <Name>GroupButton</Name>
                <Text>Edit</Text>
                <EventId>1000</EventId>
                <ValueType>Button</ValueType> <!--(1)!-->
            </Parameter>
        </Parameter>
    </Parameter>
</Parameter>
  1. When a button is added to the group, the final event ID is a combination of the <EventId> and the row index. The extraction of these values is done with bitwise shifting of the event_id value as follows:

    block_row_index = event_id >> 16
    block_event_id  = event_id - (block_row_index << 16)
    

Group one dimensional list with row

<Parameter>
    <Name>ListGroup</Name>
    <ValueType>ListGroup</ValueType>

    <Parameter>
        <Name>GroupRow</Name>
        <Text>"Field " + str($list_row + 1)</Text>
        <ValueType>Row</ValueType>

        <Parameter>
            <Name>SectionName</Name>
            <Text>Section name</Text>
            <Value>["A", "B", "C"]</Value>
            <ValueType>String</ValueType>
        </Parameter>

        <Parameter>
            <Name>Distance</Name>
            <Text>Distance</Text>
            <Value>[1000, 2000, 3000]</Value>
            <ValueType>Length</ValueType>
        </Parameter>

        <Parameter>
            <Name>GroupButtonRow</Name>
            <Text>"Group " + str($list_row + 1)</Text>
            <ValueType>Row</ValueType>
            <Parameter>
                <Name>GroupButton</Name>
                <Text>Edit</Text>
                <EventId>1000</EventId>
                <ValueType>Button</ValueType>
            </Parameter>
        </Parameter>
    </Parameter>
</Parameter>

Examples on GitHub

The entire implementation of all above mentioned features can be found in the following examples:

Placeholder