Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python dynamic function generation

Tags:

python

pyqt

I am using PyQt and want to create a menu based on a list of strings.

The problem is that when I want to call 'addAction', it requires a call-back function (for each string) that does not take any arguments.

For simple menus, this would be fine: e.g.

menu.addAction("Open", self.open)
menu.addAction("Exit", self.quit)

However, I want to just use a single function and have the 'action string' passed in as an argument.

I am wondering if python can do something like this:

def f(x, y):
    print x + 2*y



# These 2 variables are of type: <type 'function'>
callback1 = f
callback2 = f(x=7, *)
# NB: the line above is not valid python code.
# I'm just illustrating my desired functionality

print callback1(2,5)  # prints 12
print callback2(5)    # prints 17

Here is my code snippet:

def printParam(parameter):
    print "You selected %s" % parameter


# parameters = list of strings

menu_bar = QMenuBar()
menu = menu_bar.addMenu('Select Parameter')
for parameter in parameters:
    # This line will not work because the action does not pass in
    # any arguments to the function
    menu.addAction(parameter, printParam)

Any suggestions greatly appreciated

like image 811
Ciaran Avatar asked Dec 13 '22 11:12

Ciaran


2 Answers

functools.partial() allows you to supply some of the arguments ahead of time. It will allow you to make custom callbacks as you want.

>>> from functools import partial
>>> basetwo = partial(int, base=2)
>>> basetwo.__doc__ = 'Convert base 2 string to an int.'
>>> basetwo('10010')
18
like image 182
unholysampler Avatar answered Jan 03 '23 06:01

unholysampler


You can use a closure, like this:

def printParam(parameter):
    def callback():
        print "You selected %s" % parameter
    return callback

for parameter in parameters:
    menu.addAction(parameter, printParam(parameter))
like image 25
Thomas K Avatar answered Jan 03 '23 05:01

Thomas K