# Using InteractiveLine widget in Python plugin

**URL:** https://discourse.paraview.org/t/using-interactiveline-widget-in-python-plugin/16606
**Category:** ParaView Support
**Created:** [May 12, 2025, 1:39pm UTC](https://discourse.paraview.org/t/using-interactiveline-widget-in-python-plugin/16606 "2025-05-12T13:39:41Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![elynch](https://discourse.paraview.org/user_avatar/discourse.paraview.org/elynch/32/6418_2.png) [@elynch](https://discourse.paraview.org/u/elynch)
#### Post date: [May 12, 2025, 1:39pm UTC](https://discourse.paraview.org/t/using-interactiveline-widget-in-python-plugin/16606/1 "2025-05-12T13:39:41Z")

</div>

I’m trying to write a Python plugin with a line, defined by two points, as one of its inputs. If possible, I would like to use ParaView’s InteractiveLine widget to select the points so the user can interactively pick the points and see the line drawn on the screen.

One way I thought to do this was as follows:

```auto
import numpy as np
import vtk
from vtk.util.numpy_support import vtk_to_numpy, numpy_to_vtk
from vtk.util.vtkAlgorithm import VTKPythonAlgorithmBase
from paraview.util.vtkAlgorithm import smproxy, smproperty, smdomain

@smproxy.filter()
@smproperty.input(name='LineLoads', port_index=0)
class LineLoads(VTKPythonAlgorithmBase):
    def __init__ (self):
        VTKPythonAlgorithmBase. __init__ (self, nInputPorts=1, nOutputPorts=1, outputType='vtkPolyData')
        self.AxisBegin = [0.0] * 3
        self.AxisEnd = [0.0] * 3

    @smproperty.xml("""
      <DoubleVectorProperty name="AxisBegin"
        number_of_elements="3"
        default_values="0 0 0"
        command="SetAxisBegin" />
      <PropertyGroup panel_widget="InteractiveLine">
        <Property function="Point1WorldPosition" name="AxisBegin" />
        <Property function="Point2WorldPosition" name="AxisEnd" />
      </PropertyGroup>""")
    def SetAxisBegin(self, *val):
        if val != self.AxisBegin:
            self.AxisBegin = np.array(val[:3])
            self.Modified()
    def SetAxisEnd(self, *val):
        if val != self.AxisEnd:
            self.AxisEnd = np.array(val[:3])
            self.Modified()

    def RequestData(self, request, inVec, outVec):
        return 1

```

If I do that, I get a warning saying:

```auto
vtkSMPropertyGroup.cxx:194 WARN| vtkSMPropertyGroup (0x107d9b00): Failed to locate property 'AxisEnd' for PropertyGroup. Skipping.
critical: In unknown, line 0
critical: Missing required property for function 'Point2WorldPosition'.

```

So then I added the smproperty.xml decorator separately to the SetAxisBegin and SetAxisEnd functions:

```auto
    @smproperty.xml("""
      <DoubleVectorProperty name="AxisBegin"
        number_of_elements="3"
        default_values="0 0 0"
        command="SetAxisBegin" />
      <PropertyGroup panel_widget="InteractiveLine">
        <Property function="Point1WorldPosition" name="AxisBegin" />
      </PropertyGroup>""")
    def SetAxisBegin(self, *val):
        if val != self.AxisBegin:
            self.AxisBegin = np.array(val[:3])
            self.Modified()

    @smproperty.xml("""
      <DoubleVectorProperty name="AxisEnd"
        number_of_elements="3"
        default_values="0 0 0"
        command="SetAxisEnd" />
      <PropertyGroup panel_widget="InteractiveLine">
        <Property function="Point2WorldPosition" name="AxisEnd" />
      </PropertyGroup>""")
    def SetAxisEnd(self, *val):
        if val != self.AxisEnd:
            self.AxisEnd = np.array(val[:3])
            self.Modified()

```

This gives me a message that looks like:

```auto
critical: In unknown, line 0
critical: Missing required property for function 'Point2WorldPosition'.
critical: In unknown, line 0
critical: Missing required property for function 'Point1WorldPosition'.

```

Unsurprisingly, I also get two InteractiveLine widgets in the GUI. What’s the magic recipe here so that I get one line widget with Point1WorldPosition connected to my plugin’s AxisBegin and Point2WorldPosition connected to AxisEnd?

---

<div class="post-metadata">

### Author: ![elynch](https://discourse.paraview.org/user_avatar/discourse.paraview.org/elynch/32/6418_2.png) [@elynch](https://discourse.paraview.org/u/elynch)
#### Post date: [May 12, 2025, 2:57pm UTC](https://discourse.paraview.org/t/using-interactiveline-widget-in-python-plugin/16606/2 "2025-05-12T14:57:20Z")

</div>

I figured it out. The key was to put the PropertyGroup XML stuff in the decorator on the SetAxisEnd method so it would be _after_ the properties for AxisBegin and AxisEnd had already been defined.

```auto
    @smproperty.xml("""
      <DoubleVectorProperty name="AxisBegin"
        number_of_elements="3"
        default_values="0 0 0"
        command="SetAxisBegin" />""")
    def SetAxisBegin(self, *val):
        if any(val != self.AxisBegin):
            self.AxisBegin[:3] = val[:3]
            self.Modified()

    @smproperty.xml("""
      <DoubleVectorProperty name="AxisEnd"
        number_of_elements="3"
        default_values="0 0 0"
        command="SetAxisEnd" />
      <PropertyGroup panel_widget="InteractiveLine">
        <Property function="Point1WorldPosition" name="AxisBegin" />
        <Property function="Point2WorldPosition" name="AxisEnd" />
      </PropertyGroup>""")
    def SetAxisEnd(self, *val):
        if any(val != self.AxisEnd):
            self.AxisEnd[:3] = val[:3]
            self.Modified()

```
