[Tutor] Tkinter: binding functions to widgets
Scot W. Stevenson
scot@possum.in-berlin.de
Thu, 29 Aug 2002 02:43:39 +0200
Hello Alan,
One of the basic design principles I was taught is to keep the GUI code and
the actual production code as separate as possible. One of the main
reasons cited is maintenance; also, imagine you get tired of Tkinter, fall
madly in love with Qt, and dedicate your life to writing Python programs
for the KDE desktop. It is a lot easer to reuse your old stuff if you
don't have to untangle the GUI code from the production code.
Usually, you have something in the GUI that triggers an event, for example
if you press a button. Now this widget (the Button widget, for example)
has a parameter called "command" that you can use to point to a function.
What you can do is tell this function to get the value out an entry field
(such as that of an Entry widget) and pass that value to the actual logic
code that does the real work. So the chain of events is something like:
- Button press calls function given with button command [Pure Tkinter]
- Function gets value from Entry widget and passes it on to logic function
- Logic function does the real work [No Tkinter]
Once you get down to the last level, you are free to ignore that there is
any such thing as a GUI.
> --a user enters a number
> --the program outputs whether or not the number was, say, greater than 0
I have some toy Tkinter code here from when I was playing with Entry fields
that I quickly adopted to your example; it uses classes, though (which you
can probably ignore) and because I'm not that experienced either, this
might not be the best way of doing things (but then somebody will probably
correct it, so we both learn something, <g>). "showinfo", in case you are
wondering, is a pre-fab widget that is included in the tkMessageBox
module. Note that it only accepts integers, not floats or such.
If something is not clear (or flatly doesn't work - I just renamed a few
things, cut a few lines out, and put in the try/except part), please feel
free to ask, and I'll see if I understand what I did back then =8).
Y, Scot
=====================================================
from Tkinter import *
from tkMessageBox import showinfo
root = Tk()
class numberchecker(Frame):
def __init__(self, parent=None):
Frame.__init__(self, parent)
self.pack()
self.entryfield = Entry(self)
self.entryfield.insert(0, 'Type number here')
self.entryfield.pack(side=TOP, fill=X)
getbutton = Button(self, text='Go!', command=self.getnumber)
getbutton.pack(side=TOP, fill=X)
# Handel imput and delegate to logic function
def getnumber(self):
rawnumber = self.entryfield.get()
# Make sure this is really a number
try:
number = int(rawnumber)
except ValueError:
self.entryfield.delete(0, END)
self.entryfield.insert(0, '*** Not a number ***')
return
# Call program logic and display result
if self.check_number(number) == 1:
self.displaygoodnews(number)
else:
self.displaybadnews(number)
# Display good news
def displaygoodnews(self, number):
messagetext = 'Number %s is greater than 0!' % number
showinfo('Hurray!', messagetext)
# Display good news
def displaybadnews(self, number):
messagetext = 'Number %s is not greater than 0!' % number
showinfo('Oh no!', messagetext)
# Actual program logic
def check_number(self, number):
if number > 0:
return 1
else:
return 0
if __name__ == '__main__':
test = numberchecker()
test.mainloop()