Skip to content

Dynamic property palette

The property palette can be created and changed dynamically during the runtime of a PythonPart. In this chapter we are going to focus on various methods, which can control the look and layout of the elements of the property palette.

Control properties

The ControlProperties are the internal data structure for creating controls in the PythonPart property palette. The properties are responsible for a.o.:

  • text shown on the left side of the palette
  • value checking (min/max value, value list)
  • background color of the control field
  • hiding/showing and enabling/disabling a control

To modify these control properties during the runtime of the PythonPart, use the methods provided in the ControlPropertiesUtil. Using this utility, properties mentioned above can be changed in the script when the palette is initialized or with each property modification done by the user.

In a standard PythonPart the ControlPropertiesUtil object is passed as an argument to the following functions:

Implement them in your script to get the access to the methods provided in the utility.

In an interactor PythonPart the ControlPropertiesUtil must be constructed first.

from ControlPropertiesUtil import ControlPropertiesUtil
...
ctrl_prop_util = ControlPropertiesUtil(control_props_list, build_ele_list) #(1)!
  1. The control_props_list and build_ele_list are python lists containing ControlProperties and BuildingElement objects respectively. These lists are passed by the framework directly to the create_interactor function based on the .pyp file when the PythonPart is initialized.

After the utility is constructed, its methods can be used as follows:

if ...:
    ctrl_prop_util.set_text("Distance", "Distance from left") #(1)!
else:
    ctrl_prop_util.set_text("Distance", "Distance from right")
  1. In this case the text shown in the palette for the parameter Distance is changed from the default value defined in the <Text> tag in the .pyp file into Distance from left.

Hide or disable a control

Sometimes it's useful to disable or hide a control inside the property palette dynamically e.g., based on a value of another parameter. Based in the complexity of the condition, this behavior can be implemented directly in the .pyp file or in the script.

In the .pyp file

Managing the visibility and enable state of a specific input control can be done dynamically directly in the .pyp file by adding the tags <Enable> and/or <Visible> in the <Property> node.

<Parameter>
    <Name>String</Name>
    <Text>String parameter</Text>
    <Value>This is a string</Value>
    <ValueType>String</ValueType>
    <Enable>True</Enable>
    <Visible>0</Visible>
</Parameter>

To apply the condition to multiple directly consecutive parameters, put them into one virtual parameter called condition group

<Parameter>
    <ValueType>ConditionGroup</ValueType>
    <Visible>FooParameter == 2</Visible>

    <Parameter>
        <Name>BarParameter</Name>
        ...
    </Parameter>

    <Parameter>
        <Name>BazParameter</Name>
        ...
    </Parameter>
</Parameter>

Example

Here are some examples of more complex conditions for controlling the visibility.

<Enable>FooParameter == True</Enable>  <!--(1)!-->
<Visible>RadioButtonValue in [1, 5]</Visible>

<Enable>FooParameter == __StringTable.get_string("1220", "Column")</Enable>  <!--(2)!-->

<Enable>$list_row != FooParameter</Enable>  <!--(3)!-->
<Visible>NamedTupleParameter[$list_row].TupleItem</Visible>

<Visible>__is_visible_control("FooParameter") and FooParameter > 0</Visible>  <!--(4)!-->

<Enable>__is_input_mode()</Enable>  <!--(5)!-->

<Visible> <!--(6)!-->
if FooParameter &lt; 1000:
    return True:

if BarParameter &gt;<!--(7)!--> 1000:
    return True

return False
</Visible>  
  1. A logical formula including other parameters
  2. A logical formula including access to the string table
  3. A logical formula including access to the list row (in case of list parameter)
  4. A logical formula including a check for the visibility of another parameter
  5. A logical formula checking the input mode. The function __is_input_mode() returns False for PythonPart modification
  6. A multi-line logical formula
  7. Because the .pyp file uses the xml syntax, use &lt; and &gt; instead of < and > operators.

In the script

If the complexity of the enable or visible condition is so high that it cannot be implemented in the .pyp file, you must implement it in the script. Use the ControlPropertiesUtil class mentioned above. First, define a function returning True, when the control should be visible/enabled:

def initialize_control_properties(build_ele, ctrl_prop_util, _doc):
    ...
    def visible_foo_parameter(...) -> bool: #(1)!
        #perform operations to determine the visibility
        return ...

    def enable_bar_parameter(...) -> bool:
        #perform operations to determine the enable state
        return ...
  1. Provide the right parameter in (...) depending on the type of the parameter value:

    value type parameter
    single value ()
    list of values (row_index: int)
    single namedtuple (field_name: str)
    list of namedtuple (row_index: int, field_name: str)

Then assign the function to the parameter whose visibility/enable state you want to control with it. Use the set_enable_function to control the enable state or set_visible_function to control the visibility.

    ctrl_prop_util.set_visible_function("FooParameter", visible_length)
    ctrl_prop_util.set_enable_function("BarParameter", enable_length)

Example

Examples can be found here:

  • …\etc\Examples\PythonParts\PaletteExamples\Visibility.pyp
  • …\etc\PythonPartsExampleScripts\PaletteExamples\Visibility.py
  • …\etc\Examples\PythonParts\PaletteExamples\NamedTuple.pyp
  • …\etc\PythonPartsExampleScripts\PaletteExamples\NamedTuple.py
  • …\etc\Examples\PythonParts\PaletteExamples\ValueList.pyp
  • …\etc\PythonPartsExampleScripts\PaletteExamples\ValueList.py

Active page

Sometimes it's useful to do display the handles or some preview data depending on which page of the property palette is currently active. This behavior can be implemented with the set_active_palette_page_index function. You can implement it into your standard PythonPart as well as into your interactor

Dynamic text

If the text inside the property palette needs to be dynamic, this can be implemented in the script by using ControlPropertiesUtil as described in the chapter before. However, it is also possible to implement this behavior directly in the .pyp file using the <TextDyn> tag. The same can be done for the <ValueTextDyn> tag, which creates a dynamic value text.

A single line Python expression can be implemented in this tag like this:

<TextDyn>__StringTable.get_string(1003, "Placement") + ("Right" if DistanceHeader else "Left")<!--(1)!--></TextDyn>
  1. Functions from the math package are possible and can be used by math.xxx.

A multi-line Python expression can also be implemented. The Python source code for the expression must be left aligned in the .pyp file. Because the .pyp file uses the XML syntax, &lt; and &gt; operators must be used instead of < and >.

<TextDyn>
if not Dimension:
    return "Length"
if Dimension == 1:
    return "Width"
return "Height"
<TextDyn>

In case of a list parameter, the row index can be accessed with $list_row.

Example

For a complete usage of dynamic text, see the example:

  • …\etc\Examples\PythonParts\PaletteExamples\OptionalTags\TextDyn.pyp
  • …\etc\PythonPartsExampleScripts\PaletteExamples\OptionalTags\TextDyn.pyp