I wonder if it's possible to create a list of "def", to connect a list of 20 buttons, and to have a different callback for each button.
Thanks
I wonder if it's possible to create a list of "def", to connect a list of 20 buttons, and to have a different callback for each button.
Thanks
def
in Python is just a regular statement that binds a name to a function/closure. For example you can write
flist = []
for i in range(30):
def func(x, i=i):
print(x * i)
flist.append(func)
after that flist[7](6)
will return 42.
The tricky part is only i=i
in the above declaration. This is needed because a closure caputures the variable, not the current variable value. Without that i=i
all of the functions would be using the same variable i
used for looping.
Python also has some support for anonymous functions so in the above simple case the code could be shortened to
flist = []
for i in range(30):
flist.append(lambda x, i=i: print(x * i))
but lambda
s are very limited (just a single expression, no statements)
Rather than cluttering up your program with a multitude of callback functions you can do what you want with a single callback function.
The program below uses a helper function to create each button. This function passes two items of user data to each button's connect
method: the button's label text and the button's index number. When the callback is called, it receives these items of data, as well as the button widget itself. The callback can use the button widget's get_label()
method to identify the button, but passing the index number is often convenient. Passing the label text as user data is a bit redundant here, but I only did it to demonstrate the technique. (What do you expect from a demo program written in 20 minutes? :) )
#!/usr/bin/env python
''' A simple gtk2+ button demo
Written by PM 2Ring 2014.11.22
'''
import pygtk
pygtk.require('2.0')
import gtk
class ButtonDemo(object):
def button_cb(self, widget, text, data):
print "Button '%s' clicked. Data=%s. Label '%s'" % (text, data, widget.get_label())
return True
def quit(self, widget): gtk.main_quit()
def __init__(self):
win = gtk.Window(gtk.WINDOW_TOPLEVEL)
width = gtk.gdk.screen_width() // 2
height = gtk.gdk.screen_height() // 8
win.set_size_request(width, height)
win.set_title("GTK Button demo")
win.set_border_width(10)
win.connect("destroy", self.quit)
box = gtk.HBox()
box.show()
win.add(box)
def make_button(text, data):
button = gtk.Button(label=text)
button.connect('clicked', self.button_cb, text, data)
button.show()
return button
base = ord('A')
for i in xrange(5):
button = make_button('Button_%s' % chr(base + i), i)
box.pack_start(button, True)
button = gtk.Button('_Quit')
button.show()
box.pack_start(button, False)
button.connect("clicked", self.quit)
win.show()
def main():
ButtonDemo()
gtk.main()
if __name__ == "__main__":
main()