By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,846 Members | 1,191 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,846 IT Pros & Developers. It's quick & easy.

Tkinter Button command query

P: n/a
I'm new to Tkinter programming and am having trouble creating a
reusable button bar... I want to be able to feed my class a dictionary
of button names and function names, which the class will make.

My button bar is implemented a Frame subclass, which takes the button
dictionary as an argument and displays the buttons on the screen:

class OptionsBar(Frame):
def __init__(self, buttonDict, parent=None)
Frame.__init__(self, parent)
parent.someFunction() # This works fine
for (name, command) in buttonDict.items():
Button(self, text=name, command=command).pack(side=TOP,
fill=BOTH)

and then another Frame subclass, e.g. MyWindow, uses the bar as
follows:

self.buttonDict = {'Button1':'someFunction',
'Button2':'otherFunction'}
...
myBar = OptionsBar(parent=self, buttonDict=self.buttonDict)
myBar.pack(side=RIGHT)
...

def someFunction():
do button stuff

My problem is that the Button instances aren't calling the correct
functions when pressed. Is there anyway I get Button to call its
parent frame's parent frame's functions? I've tried using

self.buttonDict = {'Button1':'parent.someFunction',
'Button2':'parent.otherFunction'}

but to no avail. Hope my explanations make sense.

Any suggestions?

Cheers
PAW
Jul 18 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Paul A. Wilson wrote:
I'm new to Tkinter programming and am having trouble creating a
reusable button bar... I want to be able to feed my class a dictionary
of button names and function names, which the class will make.

My button bar is implemented a Frame subclass, which takes the button
dictionary as an argument and displays the buttons on the screen:

class OptionsBar(Frame):
def __init__(self, buttonDict, parent=None)
Frame.__init__(self, parent)
parent.someFunction() # This works fine
for (name, command) in buttonDict.items():
Button(self, text=name, command=command).pack(side=TOP,
fill=BOTH)

and then another Frame subclass, e.g. MyWindow, uses the bar as
follows:

self.buttonDict = {'Button1':'someFunction',
'Button2':'otherFunction'}
...
myBar = OptionsBar(parent=self, buttonDict=self.buttonDict)
myBar.pack(side=RIGHT)
...

def someFunction():
do button stuff

My problem is that the Button instances aren't calling the correct
functions when pressed. Is there anyway I get Button to call its
parent frame's parent frame's functions? I've tried using

self.buttonDict = {'Button1':'parent.someFunction',
'Button2':'parent.otherFunction'}

but to no avail. Hope my explanations make sense.

Any suggestions?


Use the function identifier directly instead of a string to identify the
commands, e. g:

import Tkinter
class OptionsBar(Tkinter.Frame):
def __init__(self, buttonDict, parent=None):
Tkinter.Frame.__init__(self, parent)
parent.someMethod() # This works fine only if parent is not None
for (name, command) in buttonDict.items():
Tkinter.Button(self, text=name,
command=command).pack(side=Tkinter.TOP,
fill=Tkinter.BOTH)

def aFunction():
print "a function"

class MyWindow(Tkinter.Frame):
def __init__(self, parent):
Tkinter.Frame.__init__(self, parent)
self.buttonDict = {'Button1': self.someMethod,
'Button2': aFunction}
#...
myBar = OptionsBar(parent=self, buttonDict=self.buttonDict)
myBar.pack(side=Tkinter.RIGHT)
#...

def someMethod(self):
print "some method"

root = Tkinter.Tk()
MyWindow(root).pack()
root.mainloop()

You can pass self.someMethod around as if it were a function. Python will
take care that the method is invoked with the instance denoted by self.

Note how I changed e. g. Button to Tkinter.Button. As you are already
creating reusable components you should also start to care about namespace
cluttering. If you are too lazy to type Tkinter in full beauty, use an
alias

import Tkinter as tk

and then tk.Button() etc.
Peter

PS: Do us - and yourself - the favour of using *4*-space indents. The more
people use it as a standard, the better you can tuck pieces of code from
different sources together.

Jul 18 '05 #2

P: n/a
Paul A. Wilson wrote:
I'm new to Tkinter programming and am having trouble creating a
reusable button bar... I want to be able to feed my class a dictionary
of button names and function names, which the class will make.

My button bar is implemented a Frame subclass, which takes the button
dictionary as an argument and displays the buttons on the screen:

class OptionsBar(Frame):
def __init__(self, buttonDict, parent=None)
Frame.__init__(self, parent)
parent.someFunction() # This works fine
for (name, command) in buttonDict.items():
Button(self, text=name, command=command).pack(side=TOP,
fill=BOTH)


Tkinter wants the functions, not the names of the functions. you can use
getattr() to get around this:

for (name, command) in buttonDict.items():
command = getattr(parent, command)
Button(self, text=name, command=command)...

(getattr(obj, "name") is the same as obj.name)

</F>


Jul 18 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.