[Tutor] My best GUI app so far.

Kent Johnson kent37 at tds.net
Tue Jan 11 14:56:34 CET 2005


Jacob S. wrote:
> Exception in Tkinter callback
> Traceback (most recent call last):
>   File "C:\Python24\lib\lib-tk\Tkinter.py", line 1345, in __call__
>     return self.func(*args)
> TypeError: <lambda>() takes exactly 1 argument (0 given)
> 
> I got this error when trying to send command = lambda x: self.adddigit('1')
> to makeButton - and for all of the
> rest of the digits, too. The way I fixed it was to again put *x in from of
> the x in lambda - but I left it out in the key binding.
> The reason it needs that is because the key binding sends a Tkinter
> instance, event, to the second argument whereas
> the button command does not. So to allow for both of them to use the same
> adddigit function I had to let the lambda in
> the buttons to accept extra junk. I think.

Ah, right you are. I should know better than to post untested code, it's usually buggy!

I think you need to do the same thing for add(), subtract(), multiply() and divide(). For some 
reason I don't understand, for me add works from the keyboard and multiply doesn't!?

> 
> I also took out the list self.bl due to the fact that I am no longer using
> the list of lambdas in more than one place.
> (I'm not sure I was before either)
> 
> Oh,
> 
> I get your
> whitespace
>         and readibility
> thing
>     too.  *grin*

Cool. Neatness counts! :-)

Kent

> 
>  Here's the code again.
> 
> ###Start of Calculator.py###
> from __future__ import division
> from Tkinter import *
> 
> class Application(Frame):
>      def ctb(self):
>          if self.shouldblank:
>              self.distext.set('')
>              self.shouldblank = False
> 
>      def adddigit(self, digit):
>          self.ctb()
>          self.distext.set(self.distext.get()+digit)
> 
>      def adddigitdot(self):
>          if not self.distext.get().count('.'):
>              self.ctb()
>              self.distext.set(self.distext.get()+'.')
> 
>      def equal(self):
>          if self.action:
>              self.newnum = self.distext.get()
>              self.newnum = str(eval(self.oldnum+self.action+self.newnum))
>              self.distext.set(self.newnum)
>              self.oldnum = '0'
>              self.action = ''
>              self.shouldblank = True
> 
>      def add(self):
>          self.handleOperator('+')
> 
>      def subtract(self):
>          self.handleOperator('-')
> 
>      def multiply(self):
>          self.handleOperator('*')
> 
>      def divide(self):
>          self.handleOperator('/')
> 
> 
>      def handleOperator(self, oper):
>          if self.action:
>              self.equal()
>              self.oldnum = self.distext.get()
>              self.action = oper
>          else:
>              self.oldnum = self.distext.get()
>              self.action = oper
>              self.shouldblank = True
> 
> 
>      def clear(self):
>          self.action = ''
>          self.oldnum = '0'
>          self.distext.set('0')
>          self.shouldblank = True
> 
>      def memrecall(self):
>          self.distext.set(self.memory)
>          self.shouldblank = True
> 
>      def memminus(self):
>          self.memory = str(eval(self.memory+"-"+self.distext.get()))
>          self.shouldblank = True
> 
>      def memplus(self):
>          self.memory = str(eval(self.memory+"+"+self.distext.get()))
>          self.shouldblank = True
> 
> 
>      def makeButton(self, text, command, row, column):
>          button = Button(self,text=text,command=command,width=4,height=3)
>          button.grid(row=row,column=column)
>          if len(text) == 1:
>              self.bind_all(text,lambda x: command())
> 
> 
>      def createWidgets(self):
>          self.distext = StringVar()
>          self.display
> =Entry(self,textvariable=self.distext,width=22,justify='right')
>          self.display.grid(row=0,column=1,columnspan=4)
> 
>          self.makeButton(text='0',command=lambda *x:
> self.adddigit('0'),row=5,column=1)
>          self.makeButton(text='1',command=lambda *x:
> self.adddigit('1'),row=4,column=1)
>          self.makeButton(text='2',command=lambda *x:
> self.adddigit('2'),row=4,column=2)
>          self.makeButton(text='3',command=lambda *x:
> self.adddigit('3'),row=4,column=3)
>          self.makeButton(text='4',command=lambda *x:
> self.adddigit('4'),row=3,column=1)
>          self.makeButton(text='5',command=lambda *x:
> self.adddigit('5'),row=3,column=2)
>          self.makeButton(text='6',command=lambda *x:
> self.adddigit('6'),row=3,column=3)
>          self.makeButton(text='7',command=lambda *x:
> self.adddigit('7'),row=2,column=1)
>          self.makeButton(text='8',command=lambda *x:
> self.adddigit('8'),row=2,column=2)
>          self.makeButton(text='9',command=lambda *x:
> self.adddigit('9'),row=2,column=3)
>          self.makeButton(text='.',command=self.adddigitdot,row=5,column=2)
>          self.makeButton(text="=",command=self.equal,row=5,column=3)
>          self.makeButton(text='+',command=self.add,row=5,column=4)
>          self.makeButton(text="-",command=self.subtract,row=4,column=4)
>          self.makeButton(text='x',command=self.multiply,row=3,column=4)
>          self.makeButton(text='/',command=self.divide,row=2,column=4)
>          self.makeButton(text='ON/C',command=self.clear,row=1,column=4)
>          self.makeButton(text='MRC',command=self.memrecall,row=1,column=1)
>          self.makeButton(text="M-",command=self.memminus,row=1,column=2)
>          self.makeButton(text="M+",command=self.memplus,row=1,column=3)
> 
> 
>      def __init__(self, master=None):
>          Frame.__init__(self,master)
>          self.master.title("Calculator by Jacob, Inc.")
>          self.pack(expand=True)
>          self.oldnum = '0'
>          self.memory = '0'
>          self.action = ''
>          self.shouldblank = True
>          self.createWidgets()
> 
> app = Application()
> app.mainloop()
> ###End of Calculator.py###


More information about the Tutor mailing list