# Finding GUI with the same property value

**URL:** <https://forum.inductiveautomation.com/t/finding-gui-with-the-same-property-value/11530>\
**Category:** Ignition\
**Created:** [April 19, 2016, 5:55am UTC](https://forum.inductiveautomation.com/t/finding-gui-with-the-same-property-value/11530 "2016-04-19T05:55:43Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![ian](https://avatars.discourse-cdn.com/v4/letter/i/bb73d2/32.png) [@ian](https://forum.inductiveautomation.com/u/ian)\
**Post date:** [April 19, 2016, 5:55am UTC](https://forum.inductiveautomation.com/t/finding-gui-with-the-same-property-value/11530/1 "2016-04-19T05:55:43Z")

</div>

Suppose we have GUI component A1 and A2 which are derived from the same Custom Template A. Now, suppose Template A has Template Property called Prop1.

When put both component A1 and component A2 in the same Root Container in a Window, is there any way we can do in the scripting of, let say, A1 event, to find A2 component - provided that they are the only components in the GUI which has the same Prop1 values?

The similarities between A1 and A2 are not their name - for they may have arbitrarily different names. But we know that A1 and A2 both have the same Prop1 values. Can we find the component by scripting?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 19, 2016, 11:59am UTC](https://forum.inductiveautomation.com/t/finding-gui-with-the-same-property-value/11530/2 "2016-04-19T11:59:57Z")

</div>

Containers have a .getComponents() method that will return a list of the java components inside them. You can iterate through this list testing for your criteria. You’ll probably want to check component classes, then attribute values. The possibilities are endless.

---

<div class="post-metadata">

**Author:** ![ian](https://avatars.discourse-cdn.com/v4/letter/i/bb73d2/32.png) [@ian](https://forum.inductiveautomation.com/u/ian)\
**Post date:** [April 20, 2016, 3:38am UTC](https://forum.inductiveautomation.com/t/finding-gui-with-the-same-property-value/11530/3 "2016-04-20T03:38:09Z")

</div>

That sounds great! OK, will try to look at that more. Do you happen to have any reference for me to figure out more about the methods, properties, etc which I can use? Is it in the Ignition website (I probably miss it if it does)?

---

<div class="post-metadata">

**Author:** ![ian](https://avatars.discourse-cdn.com/v4/letter/i/bb73d2/32.png) [@ian](https://forum.inductiveautomation.com/u/ian)\
**Post date:** [April 20, 2016, 4:07am UTC](https://forum.inductiveautomation.com/t/finding-gui-with-the-same-property-value/11530/4 "2016-04-20T04:07:07Z")

</div>

@pturmel: In the end, I follow your and @JGJohnson’s suggestion in the [other post](https://inductiveautomation.com/forum/viewtopic.php?f=25&t=15484) and use Template Repeater instead of Container.

Just want to ask if the Template Repeater also has getComponents() to find the list of items under it or the list of items have to be accessed differently (such as using index in ArrayList or key in HashTable?) – I am not too familiar with Java.

If it is not too difficult for you, I would also like for a minimum example on how can I get the components by checking the property – as I don’t have any idea how to write code in Java style (assuming that this can be done) in the Ignition script (since, AFAIK, the script is supposed to be written in Jython, which is also new for me)

Thanks a lot in advance!

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 20, 2016, 1:45pm UTC](https://forum.inductiveautomation.com/t/finding-gui-with-the-same-property-value/11530/5 "2016-04-20T13:45:27Z")

</div>

[quote=“ian”]Just want to ask if the Template Repeater also has getComponents() to find the list of items under it or the list of items have to be accessed differently (such as using index in ArrayList or key in HashTable?)[/quote]I briefly looked at this once – there’s more than one level of nesting, but getComponents() at each level will expose everything.[quote=“ian”]I am not too familiar with Java.[/quote]You don’t have to be familiar with writing Java, but you will have to get familiar with [Java Swing](http://docs.oracle.com/javase/8/docs/api/javax/swing/package-summary.html) objects to really apply these techniques. All of Ignition’s components are subclasses of JComponent, and therefore have its methods and properties.[quote=“ian”]If it is not too difficult for you, I would also like for a minimum example on how can I get the components by checking the property[/quote]Something like this on a button’s actionPerformed event:`from com.inductiveautomation.factorypmi.application.components.template import TemplateHolder
root = event.source.parent
for comp in root.components:
	print comp.name, comp.class
	if TemplateHolder.isInstance(comp):
		print " %s" % comp.templatePath
		if comp.name.startswith('signal'):
			print " One of my signals!"`A few further notes:[ol][li]In jython, java getter and setter methods that follow NetBeans naming conventions are turned into properties. So .getComponents() can be written .components instead. And such a property will be assignable (writable) if the matching java set\*(newValue) method exists.[/li][li]Java objects have a .getClass() method that you can use to obtain the information you need to import component types. (Should be obvious if you run this script.)[/li][li]When you hover over a property in the property pane of Ignition’s designer, it will show you the jython name of that property for that component.[/li][li]Containers and groups will show up in your list. You will need a nested loop to find the components inside them.[/li][li]When you are feeling good about the above, the next step is [java reflection](https://inductiveautomation.com/forum/viewtopic.php?f=70&t=13566).[/li][/ol]

---

<div class="post-metadata">

**Author:** ![ian](https://avatars.discourse-cdn.com/v4/letter/i/bb73d2/32.png) [@ian](https://forum.inductiveautomation.com/u/ian)\
**Post date:** [April 25, 2016, 4:34am UTC](https://forum.inductiveautomation.com/t/finding-gui-with-the-same-property-value/11530/6 "2016-04-25T04:34:07Z")

</div>

Thanks for your help! I currently can progress up to the stage where I can detect the root container component, listing the components and found the component which has the property matches.

However, as I want to get the sub-component of the component with matching property, I encounter another error:

This happen when I try to use the “comp” of the “root.components” with “getComponent(‘my signal name’)” method. Usually, we do that to get child component in Ignition. But somehow I got this error when I use the Java wrapper?

[quote]TypeError: getComponent(): 1st arg can’t be coerced to int

```
at org.python.core.Py.TypeError(Py.java:235)
at org.python.core.PyReflectedFunction.throwError(PyReflectedFunction.java:209)
at org.python.core.PyReflectedFunction.throwBadArgError(PyReflectedFunction.java:312)
at org.python.core.PyReflectedFunction.throwError(PyReflectedFunction.java:321)
at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:167)
at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:204)
at org.python.core.PyObject. __call__ (PyObject.java:404)
at org.python.core.PyObject. __call__ (PyObject.java:408)
at org.python.core.PyMethod. __call__ (PyMethod.java:124)
at org.python.pycode._pyx256.f$0(<event:mouseEntered>:55)
at org.python.pycode._pyx256.call_function(<event:mouseEntered>)
at org.python.core.PyTableCode.call(PyTableCode.java:165)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1275)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:623)
at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.runActions(ActionAdapter.java:168)
at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.invoke(ActionAdapter.java:265)
at 

```

[/quote]

---

<div class="post-metadata">

**Author:** ![ian](https://avatars.discourse-cdn.com/v4/letter/i/bb73d2/32.png) [@ian](https://forum.inductiveautomation.com/u/ian)\
**Post date:** [April 25, 2016, 5:44am UTC](https://forum.inductiveautomation.com/t/finding-gui-with-the-same-property-value/11530/7 "2016-04-25T05:44:19Z")

</div>

In the end, I use another for loop and if comp.name == ‘my signal component’ to make it work. Nevertheless, I have a custom property called `IsSelected` in my component.

When we use “normal” Ignition script, we could get and assign the property straightforwardly

```auto
myComponent.IsSelected = True
```

But when I try to do that in my component:

```auto
comp.IsSelected = True
```

it generates error, saying that there is no [i]Attribute/i called IsSelected:

[quote]AttributeError: ‘com.inductiveautomation.vision.api.client.componen’ object has no attribute ‘IsSelected’

```
at org.python.core.Py.AttributeError(Py.java:173)
at org.python.core.PyObject.noAttributeError(PyObject.java:930)
at org.python.core.PyObject.object ___setattr__ (PyObject.java:3761)
at org.python.core.PyObject.object ___setattr__ (PyObject.java:3732)
at org.python.core.PyObject$object ___setattr___ exposer. __call__ (Unknown Source)
at org.python.core.PyObjectDerived. __setattr__ (PyObjectDerived.java:990)
at org.python.pycode._pyx331.f$0(<event:mouseEntered>:77)
at org.python.pycode._pyx331.call_function(<event:mouseEntered>)
at org.python.core.PyTableCode.call(PyTableCode.java:165)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1275)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:623)
at

```

[/quote]

When I print out the comp.properties(), it shows the following.

`array(com.inductiveautomation.factorypmi.application.binding.DynamicPropertyDescriptor, [IsSelected, NotSelectedColor, SelectedColor])
`

Note that the IsSelected property is there, except that I cannot assign it with the way I show above. How do I do that?

I start to get confused about “Attribute” and “Property” here…

---

<div class="post-metadata">

**Author:** ![ian](https://avatars.discourse-cdn.com/v4/letter/i/bb73d2/32.png) [@ian](https://forum.inductiveautomation.com/u/ian)\
**Post date:** [April 25, 2016, 5:50am UTC](https://forum.inductiveautomation.com/t/finding-gui-with-the-same-property-value/11530/8 "2016-04-25T05:50:48Z")

</div>

Update:

When I try to get the property IsSelected from the “array”(?) by:

```auto
comp.properties['IsSelected'] = True
```

It generates error saying: “The array index must be integer”.

OK make sense, so I change the above code to get the index 0 property since it is where the IsSelected is property is:

```auto
comp.properties[0] = True
```

But it generates another error:

[quote]TypeError: can’t convert True to com.inductiveautomation.factorypmi.application.binding.DynamicPropertyDescriptor

```
at org.python.core.Py.TypeError(Py.java:235)
at org.python.core.Py.tojava(Py.java:515)
at org.python.core.PyArray.pyset(PyArray.java:1472)
at org.python.core.PySequence$1.setItem(PySequence.java:431)
at org.python.core.SequenceIndexDelegate.checkIdxAndSetItem(SequenceIndexDelegate.java:46)
at org.python.core.SequenceIndexDelegate.checkIdxAndSetItem(SequenceIndexDelegate.java:28)
at org.python.core.PySequence.seq ___setitem__ (PySequence.java:360)
at org.python.core.PySequence. __setitem__ (PySequence.java:356)
at org.python.pycode._pyx348.f$0(<event:mouseEntered>:78)
at org.python.pycode._pyx348.call_function(<event:mouseEntered>)
at org.python.core.PyTableCode.call(PyTableCode.java:165)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1275)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:623)

```

[/quote]

I run out of bullet here…

---

<div class="post-metadata">

**Author:** ![ian](https://avatars.discourse-cdn.com/v4/letter/i/bb73d2/32.png) [@ian](https://forum.inductiveautomation.com/u/ian)\
**Post date:** [April 25, 2016, 6:43am UTC](https://forum.inductiveautomation.com/t/finding-gui-with-the-same-property-value/11530/9 "2016-04-25T06:43:29Z")

</div>

Hi pturmel,

In the end I try to inspect the component using the inspect.py (java.reflection()) which you created and manage to figure out that there is a setPropertyValue() method there. I use it to set my property’s value and it is now OK.

Thanks! It is really helpful! 😃

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 25, 2016, 10:38am UTC](https://forum.inductiveautomation.com/t/finding-gui-with-the-same-property-value/11530/10 "2016-04-25T10:38:34Z")

</div>

getPropertyValue() and setPropertyValue() are documented in the [Ignition Manual](https://docs.inductiveautomation.com/display/DOC/Component+Scripting). They used to be needed everywhere when accessing custom properties of components, but IA tweaked their event routines to coerce python to access them just like built-in properties. At least for event.source, chains of .getComponent() on event.source, and ‘self’ in custom component methods.  
{ I haven’t figured out how they did it – I’d like to apply that treatment to ‘binding.target’ in my [Simulation Aids](http://marketplace.inductiveautomation.com/moduledetail?moduleId=93) module’s expression functions. }

---

<div class="post-metadata">

**Author:** ![ian](https://avatars.discourse-cdn.com/v4/letter/i/bb73d2/32.png) [@ian](https://forum.inductiveautomation.com/u/ian)\
**Post date:** [April 26, 2016, 5:38am UTC](https://forum.inductiveautomation.com/t/finding-gui-with-the-same-property-value/11530/11 "2016-04-26T05:38:55Z")

</div>

> [@](#):
>
> getPropertyValue() and setPropertyValue() are documented in the Ignition Manual.

Now that you mention it, I started to recall somewhere in my memory that there was such thing in the Inductive University video. I must really have forgotten it... :S still, thanks a lot for your help!

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 13, 2018, 11:00pm UTC](https://forum.inductiveautomation.com/t/finding-gui-with-the-same-property-value/11530/12 "2018-07-13T23:00:45Z")

</div>

Note for future archeologists... the python wrapper behavior has been deciphered... see this post:

> [@Transaction groups triggered expression item updating when trigger is false](http://forum.inductiveautomation.com/t/transaction-groups-triggered-expression-item-updating-when-trigger-is-false/17196/19):
>
> So with some feedback from IA, I’ve spun up a new version, and I consider this one to be a [release candidate.](https://www.automation-pros.com/ignition/Simulation%20Aids-1.7.7.1803281441.modl) Two changes were made: The classes/interfaces to be checked within the adapter itself were adjusted to include the [VisionComponent](http://files.inductiveautomation.com/sdk/javadoc/ignition79/793/com/inductiveautomation/vision/api/client/components/model/VisionComponent.html) interface. I left the [DynamicPropertyProvider](http://files.inductiveautomation.com/sdk/javadoc/ignition79/793/com/inductiveautomation/factorypmi/application/binding/DynamicPropertyProvider.html) interface in the checklist in case there are third-party modules supplying components without the VisionComponent interface. The static block in my module hook was changed to first check if Py.java2py() yi…
