Issue with passing functions with arguments

What I am trying to do is create a popup menu where the functions to call from the popup have arguments. I basically want to have one function that I call with different parameters based on the item selected in the list.

The problem I am seeing is that when I try to append the function with arguments to the list of functions, it is being called immediately instead of being appended.

Here is a simple example that illustrates what I am trying to do:

[color=#0000FF]def say(event, name):
import system
system.gui.messageBox(name)

menuNames = []
menuFunctions = []

menuNames.append(“Hello”)
menuNames.append(“Goodbye”)

menuFunctions.append(say(event,“Hello World”))
menuFunctions.append(say(event,“Goodbye World”))

menu = system.gui.createPopupMenu(menuNames, menuFunctions)
menu.show(event)[/color]

When I click the button this event is tied to, I get 2 message boxes popping up with the text I sent, and nothing gets added to the function list and I get no pop up menu, or rather, I get an empty popup menu.

As soon as I add () to my function names they get called immediately. Is there a way to pass functions with arguments without having the functions execute immediately?

That is because you are calling the function when appending it to the array rather than appending a declaration. Do the following:[code]menuNames = []
menuFunctions = []

menuNames.append(“Hello”)
menuNames.append(“Goodbye”)

def say(event=event, name=“Hello World”):
import system
system.gui.messageBox(name)
menuFunctions.append(say)

def say(event=event, name=“Goodbye World”):
import system
system.gui.messageBox(name)
menuFunctions.append(say)

menu = system.gui.createPopupMenu(menuNames, menuFunctions)
menu.show(event)[/code]

What if I don’t know how many different variables there will be or even what they will be?

I have a folder with x number of applications in it. I want the script to examine that folder and build a list of application names for the popup, and then run the application the user chooses from the popup.

My original way of thinking was to pass the application name as an argument and have the method run it.

Is it not possible to append a function with arguments to a list?

Ok, I got it to work by creating a JPopupMenu. I then used event.getActionCommand() to get the name of the file I wanted to open from the menuItem selected in the popup.

For my own reference, is there no way to append a function with arguments to a list without calling the function instead?

I think the only way to do this would be to make function that took the arguments you wanted and created a function bound to those arguments. It’s a bit abstract. Google for closure.

[code]def makeFunc(arg1, arg2, arg3):
def realFun(arg1=arg1, arg2=arg2, arg3=arg3):
#do something with the arguments

list = []
list.append(makeFunc(“Hello”, 83.79, 0))
list.append(makeFunc(“World”, 27.99, 1))
[/code]

Thanks Carl, I was trying to do the same thing and your answer helped greatly. I needed to edit your answer however and use this:

def make_addToTrend(event, tag):
	def addToTrend(event=event, tag=tag):
		system.gui.messageBox(tag, "Message")
	return addToTrend  // this line is important to add!!!

items = ['Running', 'Faulted', 'Mode']
functions = [make_addToTrend(event, item) for item in items]

menu = system.gui.createPopupMenu(items, functions)
# Resize the menu item font sizes to 16pt
for item in menu.getSubElements():
	item.setFont(item.getFont().deriveFont(16.0))
menu.show(event, 0, 0)

I basically only had to add this line to the bottom of the ‘make’ function:
return addToTrend

2 Likes