Hi everyone,
this script intends to reset the ValueLists based on their Nicknames, it is very simple but an error has occurred :
> the obj GH_ValueList (undocumented in Grasshoppers SDK) has no attribute “Value” (line 15, in the script).
Can someone suggest me the right attribute or the way to find the attributes available?
Thanks a lot.
People with better understanding of GH will probably say this is a big no no
But I found this SelectItem()
method of GH_ValueList
and it takes an index integer
In a ghpython component, you can use dir() and the inspect module to help get information about various objects. Granted, it can take a little digging when working with the grasshopper namespace, but it’s doable. (whether it SHOULD be done in the first place…from within a ghpython component,
is a debate for another day )
Accessing the items in the value list would be something like this:
(assuming valuelist has been named “MyCustomValueList”)
1 - Read Values from Value List component.
As far as I know, since there is no updating happening here, you don’t need to expire anything.
import Rhino
if x:
for obj in ghenv.Component.OnPingDocument().Objects:
if obj.NickName == "MyCustomValueList":
for v in obj.Values:
print v.Name, v.Value
2 - Update Values in a Value List (example of inspect module commented at end)
Now, if you want to replace all the values, that’s pretty straight forward. You Clear the existing list,
then add your new values, (as STRINGS!), and then expiring.
import Rhino
import Grasshopper
import inspect
if x:
for obj in ghenv.Component.OnPingDocument().Objects:
if obj.NickName == "MyCustomValueList":
obj.Values.Clear()
obj.Values.Add(Grasshopper.Kernel.Special.GH_ValueListItem("MyNewName1", "0.01"))
obj.Values.Add(Grasshopper.Kernel.Special.GH_ValueListItem("MyNewName2", str(1)))
obj.Values.Add(Grasshopper.Kernel.Special.GH_ValueListItem("EDITME", '"MyThirdStringChoice"'))
obj.SelectItem(2)
obj.ExpireSolution(True)
# using inspect to show all available properties of an object
"""for member in inspect.getmembers(Grasshopper.Kernel.Special.GH_ValueList):
#print type(member[1])
#if type(member[1]).__name__ == "getset_descriptor": #properties
print member[0],": ",member[1]
3 - Updating a specfic value in a value list:
This seems like kind of a long walk, but I think, the safest way is to find your valuelist, copy the valuelistvalues to a new (pythyon)list, find the value you want in the value list, modify it in the python list, then clear the valuelist components values, and re-add them from the copied list…like i said, feels like a long walk, but I’m pretty sure that’s the safest way, from within ghpython.
import Rhino
import Grasshopper
import sys
NewValuesList = []
def checkValues():
try:
for obj in ghenv.Component.OnPingDocument().Objects:
if obj.NickName == "MyCustomValueList": #find desired valuelist component
for v in obj.Values: #copy original values to new nested list
NewValuesList.append([v.Name, v.Value])
for counter, v in enumerate(obj.Values):
if v.Name == "EDITME": #find desired valuelist item
NewValuesList.pop(counter)
#Note: valuelist component takes strings, if your desired output value
# is a string, you must enclose the quoted string with single quotes".
NewValuesList.insert(counter, ["MyUpdatedName3", '"MyupdatedValue"'])
# values are stored, now we clear the whole list, (this avoids the
# "Collection was modified; enumeration operation may not execute" error you get if you
# try to update an individual value list item while enumarating through the list.
obj.Values.Clear()
# Loop through the list and add our "new" values to the value list component
for v in NewValuesList:
obj.Values.Add(Grasshopper.Kernel.Special.GH_ValueListItem(v[0].ToString(), v[1].ToString()))
obj.SelectItem(2)
obj.ExpireSolution(True)
except Exception, ex:
ghenv.Component.AddRuntimeMessage(Grasshopper.Kernel.GH_RuntimeMessageLevel.Warning,str(sys.exc_info()[1]))
if x:
checkValues()
ghpy_setValueList.gh (8.1 KB)