Parameter with Python tuple
Tuple
The value of the PythonPart parameter can be created as a tuple. There are several ways, how to present this parameter in the property palette:
Each element of the tuple can be shown in a separate row, like this.
All control for each tuple element can be shown in one row by wrapping the tuple parameter in a row parameter.
<Parameter>
<Name>OneRowTupleRow</Name>
<Text>Sizes</Text><!--(1)!-->
<ValueType>Row</ValueType>
<Parameter>
<Name>OneRowTuple</Name>
<Text></Text><!--(2)!-->
<Value>(1500,2000,3000)</Value>
<ValueType>Tuple(Length,LengthComboBox,Length)</ValueType>
<ValueList>,1000|2000|3000|4000|5000,</ValueList>
</Parameter>
</Parameter>
- This text will be shown on the left side of the palette
- No need to define here anything, the text for the palette is taken from the row
By adding the <Value>
tag to the row and setting it to 1, you can stretch the controls
over the entire width of the palette, making them more visible
<Parameter>
<Name>FullOneRowTupleRow</Name>
<Text>Sizes</Text>
<ValueType>Row</ValueType>
<Value>1</Value>
<Parameter>
<Name>FullOneRowTuple</Name>
<Text></Text>
<Value>("Sizes",2000,2000,3000)</Value>
<ValueType>Tuple(Text,Length,LengthComboBox,Length)</ValueType>
<ValueList>,,1000|2000|3000|4000|5000,</ValueList>
</Parameter>
</Parameter>
List of tuples
You can create a tuple parameter also as a list. This can also be done in several ways.
<Parameter>
<Name>ListMultiRowTuple</Name>
<Text>Length|Width|Height</Text><!--(4)!-->
<Value>[(1000,2000,3000),(1200,2000,3200),(1400,2000,3400)]</Value> <!--(1)!-->
<ValueType>Tuple(Length,LengthComboBox,Length,Separator<!--(3)!-->)</ValueType>
<ValueList>,1000|2000|3000|4000|5000,</ValueList><!--(2)!-->
</Parameter>
- Put the initial values in brackets to initialize the tuple parameter as a list.
In case of simple values, like integers or strings, you can separate them with a comma
,
. In case of more complex values (e.g. Line2D(...)), separate them with a semicolon;
. - The values for the combo box has to be specified here. For the first and third length parameter the values don't have to be specified, that is why there is nothing before the firs and after the second comma
- Adding the separator here will group the controls optically
- Separate the texts for individual controls with a vertical line.
<Parameter>
<Name>ListOneRowTuple</Name>
<Text></Text> <!--(1)!-->
<TextDyn>f"Sizes {$list_row + 1}"</TextDyn> <!--(2)!-->
<Value>[(1500,2000,3000),(1700,2000,3200),(1900,2000,3400)]</Value>
<ValueType>Tuple(Length,LengthComboBox,Length)</ValueType>
<ValueList>,1000|2000|3000|4000|5000,</ValueList>
</Parameter>
- Leaving the
<Text>
tag empty will create all the controls in one row - Optionally, you can place a text on the left side of the palette. Use the
<TextDyn>
tag as described here.
By wrapping the tuple parameter in a row parameter with the <Value>
tag set to 1, you can
stretch the controls over the entire width of the palette. This would make them look similar
to a table.
<Parameter>
<Name>FullOneRowTupleRow</Name>
<Text></Text>
<ValueType>Row</ValueType>
<Value>1</Value>
<Parameter>
<Name>ListFullOneRowTuple</Name>
<Text></Text>
<TextDyn>f"Vector {$list_row + 1}"</TextDyn>
<Value>[(Vector3D(1500,3000,3000),True),(Vector3D(1700,3000,3200),True),(Vector3D(1900,3000,3400),True)]</Value>
<ValueType>Tuple(Vector3D,CheckBox)</ValueType>
<Dimensions>TupleCount</Dimensions>
</Parameter>
</Parameter>
Named tuple
The value of the PythonPart parameter can be created as a Python namedtuple object, defined by the used value types. For each value type, an appropriate control will be created in the palette.
<Parameter>
<Name>UShape</Name>
<Text>,Diameter,Concrete cover,Top length,Bottom length</Text><!--(1)!-->
<Value>Param01.png|12|30|1000|2000</Value><!--(2)!-->
<ValueType>namedtuple(Picture,ReinfBarDiameter,ReinfConcreteCover,Length,Length)</ValueType>
<NamedTuple>
<TypeName>UShape</TypeName>
<FieldNames>Picture,Diameter,Cover,Length1,Length2</FieldNames>
</NamedTuple>
</Parameter>
-
Text for each control must be defined and separated with coma. If only one or no text is defined, all controls will be placed in one row like this:
-
The default values must be separated with
|
character.A combination with the Python list is possible. In this case the default values for each row must be separated by
;
List of named tuples
A parameter can be defined as a list of more than one namedtuple
<Parameter>
<Name>UShapeList</Name>
<Text>,Diameter,Concrete cover,Top length,Bottom length,"Group " + str($list_row + 1)|Edit</Text>
<Value>[Param01.png|12|30|1000|2000|0|;
Param02.png|12|30|1000|2000|0|;
Param03.png|12|30|1000|2000|0|]
</Value>
<EventId>0,0,0,0,0,1000<!--(1)!-->,0</EventId>
<ValueType>namedtuple(Picture,ReinfBarDiameter,ReinfConcreteCover,Length,Length,Button<!--(2)!-->,Separator)</ValueType>
<NamedTuple>
<TypeName>UShape</TypeName>
<FieldNames>Picture,Diameter,Cover,Length1,Length2,Button,Separator</FieldNames>
</NamedTuple>
<MinValue>,,,100,200,,</MinValue><!--(3)!-->
</Parameter>
-
One of the elements of the namedtuple is a Button, which must have an
<EventID>
defined. As the namedtuple consists of 7 elements, the<EventID>
must also be a list consisting of 7 integers, but only one of them is relevant. -
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: -
All optional tags can be used in the tuple parameter. An entry must be created for each value type, separated by a comma.
Tip
See this chapter to learn how to show/hide or disable/enable a specific control of a namedtuple.
Controlling the palette text
Each row of the list can be provided with its own text in the property palette. This text is a part of the namedtuple and can be addressed in the script. To do this, the first field in the named tuple must be set to DisplayText and filled with the string for the row text. The value for the RowText field must be created in the xxx.py file. Here is an example:
stirrup_list = build_ele.StirrupList.value
for i in range(1, build_ele.ItemCount.value - 1):
stirrup_list[i] = stirrup_list[i]._replace(RowText = "Inside " + str(i))
stirrup_list[0] = stirrup_list[0]._replace(RowText = "Top")
if build_ele.ItemCount.value > 1:
stirrup_list[-1] = stirrup_list[-1]._replace(RowText = "Bottom")
The result may look like this: