Trying to create properties when another property is changed. I got this to work so that when I start the simulation it creates those new properties. But I want to create those before I start the simulation so I can input values in them.
def showOutFeeds(value):
print("Hello World")
comp=getComponent()
for i in range(value):
comp.createProperty(VC_INTEGER, "OutX"+str(i+1))
and
Where should I put that OnChanged event so it would create those properties before starting simulation.
Additional question is how do I delete these code created properties when simulation is reseted?
the line: OutFeeds.OnChanged = function() is off.
For events you do not exactly want to evaluate a function, but rather give it a function reference. For example
def OnRun():
OutFeeds=comp.getProperty("numberOfOutFeeds")
OutFeeds.OnChanged = showOutFeeds #this is now a function reference instead of evaluation
def showOutFeeds(*args):
print(args)
If you want to toss in a parameter inside an event function, you can create an inline function and return a reference. Alternative options are to use global keyword.
def OnRun():
OutFeeds=comp.getProperty("numberOfOutFeeds")
OutFeeds.OnChanged = showOutFeeds(OutFeeds.Value)
def showOutFeeds(value):
def InlineFun(*args)
print("Hello World")
comp=getComponent()
for i in range(value):
comp.createProperty(VC_INTEGER, "OutX"+str(i+1))
return InlineFun
If you simply want to create some values before you start the simulation (so basically in def OnRun) you just write the snippet of code outside any function, making them global.
# write stuff here instead
# or here and then compile
# your OnChanged event doesn't really need to be inside OnRun function
# Just make sure that the OutFeeds is created before you access the event function.
def OnRun():
OutFeeds=comp.getProperty("numberOfOutFeeds")
OutFeeds.OnChanged = showOutFeeds(OutFeeds.Value)
File “ComponentMover::PythonScript”, line 10, in showOutFeeds
TypeError: int() argument must be a string or a number, not ‘vcProperty’
when I compile the code it works fine. And prints number which is in numberOfOutfeeds property but when i change the value in the property it says that error above. I’ve tried to force it to integer but not working.
How did you create the property “numberOfOutFeeds” in the first place? If you did it via modelling tab and created an integer type property as seen in figure 1, you should be fine. Otherwise I’d need a bit more extra info.
Figure 1
From the looks of it you’re trying to create multiple properties through your for i in range(value) loop. Properties are created ONCE and if you want to modify it, it’s better to just delete it and re-create. From the looks of it the loop attempts to create properties that take integers in, and the name is OutX1, OutX2… and so on.
I think you want to create ONE property that has multiple stepvalues, instead of multiple properties with different names.
Also please note that createProperty returns a vcProperty.
I also cannot replicate your issue. Figure 2 shows this.
I’ll let this sit for the weekend and will be back on this matter on monday. Mabe with fresher thoughts and brains
Have a great weekend!
P.S Yes I’ve created it form the properties menu and I’m trying to make multiple outfeed positions. So when the user gives the number of out feeds it creates properties for those outfeeds so the user can feed the x and y coordinates where those are in the warehouse.
I’m making an warehouse initial inventory creator and this is for that.
prop.myEvent = yourFunction
vs.
prop.myEvent = yourFunction()
The lower one evaluates the function (runs it) while the top one gives it a function reference. Events need function reference which is why I made Inline function which is returned as a function reference.
The more “normal” way of doing it here would be to get the property as a global variable.
The code “could” look something like this…
comp = getComponent()
OutFeeds = comp.getProperty("numberOfOutFeeds")
val = OutFeeds.Value
def showOutFeeds(*args)
global val
# rest of your code
def OnRun():
global val
val = OutFeeds.Value
OutFeeds.OnChanged = showOutFeeds
I realized that I need to read the value when it is changed so I did it like this
def showOutFeeds():
def InLineFun(*args):
value=comp.getProperty("numberOfOutFeeds").Value
for i in range(10):
propX=comp.getProperty("Out"+str(i+1)+" X")
propY=comp.getProperty("Out"+str(i+1)+" Y")
if propX:
comp.deleteProperty("Out"+str(i+1)+" X")
if propY:
comp.deleteProperty("Out"+str(i+1)+" Y")
for i in range(value):
propX=comp.getProperty("Out"+str(i+1)+" X")
propY=comp.getProperty("Out"+str(i+1)+" Y")
if not propX:
comp.createProperty(VC_INTEGER, ("Out"+str(i+1)+" X"))
comp.getProperty("Out"+str(i+1)+" X").WritableWhenSimulating=False
if not propY:
comp.createProperty(VC_INTEGER, ("Out"+str(i+1)+" Y"))
comp.getProperty("Out"+str(i+1)+" Y").WritableWhenSimulating=False
return InLineFun
OutFeeds=comp.getProperty("numberOfOutFeeds")
OutFeeds.OnChanged =showOutFeeds()
In this case you can just delete the InLineFun and make it look like this…
def showOutFeeds(*args):
value=comp.getProperty("numberOfOutFeeds").Value
for i in range(10):
propX=comp.getProperty("Out"+str(i+1)+" X")
propY=comp.getProperty("Out"+str(i+1)+" Y")
if propX:
comp.deleteProperty("Out"+str(i+1)+" X")
if propY:
comp.deleteProperty("Out"+str(i+1)+" Y")
for i in range(value):
propX=comp.getProperty("Out"+str(i+1)+" X")
propY=comp.getProperty("Out"+str(i+1)+" Y")
if not propX:
comp.createProperty(VC_INTEGER, ("Out"+str(i+1)+" X"))
comp.getProperty("Out"+str(i+1)+" X").WritableWhenSimulating=False
if not propY:
comp.createProperty(VC_INTEGER, ("Out"+str(i+1)+" Y"))
comp.getProperty("Out"+str(i+1)+" Y").WritableWhenSimulating=False
OutFeeds=comp.getProperty("numberOfOutFeeds")
OutFeeds.OnChanged =showOutFeeds