Controlling the order that widgets appear in the GUI for a Python algorithm plugin

I have created a plugin using the Python algorithm. It has five different UI widgets created by using @smproperty and @smdomain decorators with three of the widgets set as boolean checkboxes, one widget set as a double vector slider and the last widget set as a string vector with a dropdown menu. I want to have my widgets ordered within the filter’s ParaView GUI so that one of my boolean checkbox widgets is above the string vector widget followed by the double vector widget. Unfortunately, I have not figured out how to order any of my widgets in the GUI and the string vector widget is always at the top and the double vector widget is placed between the boolean checkbox widgets. Is there a way to code the widgets that can control the order they appear in the GUI?

Hi @lpalmstrom. I know this question has been hanging out here for a while. That’s mainly because I didn’t know the answer and wanted to figure out why properties were ordered the way they are

Unfortunately, there isn’t a good way to specify an ordering on the properties. As it turns out, the properties are ordered alphabetically by the name of the command attribute, which is rather arbitrary. I’ve created an issue to add a smarter way to order properties in future versions of ParaView.

I’ve spoken too soon. There is a hack you can try now.

First, identify which of your properties shows up on the bottom of the UI. We’ll modify the definition of that property by manually specifying the XML that the Python algorithm magically generates behind the scenes for you. Let’s say that is one of the boolean checkbox widgets, which uses the @smproperty.intvector decorator. Let’s name it “MyCheckbox”. We’re going to turn

@smproperty.intvector(name="MyCheckbox")

into the equivalent XML for the property. Then we’re going to add XML to group your widgets in order.

Replace the above decorator with

    @smproperty.xml("""
    <IntVectorProperty name="MyCheckbox"
            number_of_elements="1"
            command="SetMyCheckbox">
        </IntVectorProperty>

        <PropertyGroup label="Ordered Widgets">
            <Property name="MyCheckbox" />
            <Property name="StringProp" />
            <Property name="DoubleProp" />
        </PropertyGroup>""")

The PropertyGroup lets you manually order the properties. I’ve made up two others here, StringProp and DoubleProp - use the names of your properties here instead.

Why do you have to do this for the property that shows up at the bottom you might ask? Well, PropertyGroups must appear in the generated XML after the properties they reference are defined in the XML, and we figure that out by looking for the bottom property in the UI which corresponds to the last property definition in the XML, then we declare our PropertyGroup after that. Phwew, told you it was a hack. But, it works for now.

Having a way to specify the order or just ordering by definition in the Python file would greatly simplify this.

1 Like

Hi Cory. Thanks for your suggestion. I tried adding the PropertyGroup code to the @smproperty.xml code of the last widget that appeared in the GUI, but unfortunately when I run the new code the order of the widgets did not change. I also did not receive any errors when I loaded and applied the filter. Do you know of any other hacks I could potentially use to change the order of the widgets? In case it helps, I am loading and applying my filter on ParaView 5.10.1 (the version downloaded from ParaView-5.10.1-MPI-OSX11.0-Python3.9-arm64.dmg) and I am using a MacBook Pro with an M1 Max chip. Thanks for your help!

Hmm, I’m not sure why that wouldn’t work for you, unless the PropertyGroup were being written too early in the generated XML, there were a syntax error, an old version of the plugin was being loaded, etc.

I’m afraid I can’t think of any other hacks. We really should order properties in the order they are defined in the Python script.

Hi Cory. I ended up figuring out why my original code for the PropertyGroup wasn’t working. It turns out that I was using the wrong Property name for the double vector slider and string vector widgets. I was assuming that I would use the name defined for the setters (which is also the name that shows up in the GUI) rather than the name I gave for the getters for these two widgets, since the Property name for the other three widgets with boolean checkboxes are defined with the setters rather than the getters. When I switched to using the names defined in the getters for these two widgets for their Property names under the PropertyGroup code, then the widgets were ordered correctly. Thanks for trying to help me out!