当前位置: 动力学知识库 > 问答 > 编程问答 >

string - python GUI TypeError: 'str' object is not callable

问题描述:

Ok so I'm supposed to make a basic calculator using GUI in python. I completed that task with all buttons working. Now for step 2, I'm supposed to inherit the original calculator class and create a new class called BetterCalculator, which adds in the buttons sqrt, log, pct, and pow. I have got everything working except for the pow button and when I run the program with what the teacher calls a driver, I get this error:

 Exception in Tkinter callback

Traceback (most recent call last):

File "C:\Python33\lib\tkinter\__init__.py", line 1475, in __call__

return self.func(*args)

File "E:\calculator\Calculator in class\calculator.py", line 102, in do3

self.n.set(self.n.get()+'3')

TypeError: 'str' object is not callable

and here is my code:

 #Windows basic built-in interface library.

import tkinter

import math

class Calculator:

def __init__(self):

self.win = tkinter.Tk() # Window object created

# Create frames for buttons. Win frame, topFrame(label, display) \

# bottomFrame (numberFrame

self.topFrame = tkinter.Frame(self.win)

self.bottomFrame = tkinter.Frame(self.win)

self.numbersFrame = tkinter.Frame(self.bottomFrame)

self.no123Frame = tkinter.Frame(self.numbersFrame)

self.no456Frame = tkinter.Frame(self.numbersFrame)

self.no789Frame = tkinter.Frame(self.numbersFrame)

self.no0DFrame = tkinter.Frame(self.numbersFrame)

self.optsFrame = tkinter.Frame(self.bottomFrame)

# Create object Label to use for input and output. StringVar is a class.

self.n = tkinter.StringVar()

# Display object created

self.display = tkinter.Label(self.topFrame, textvariable = self.n, bg = 'white', font = 12, height = 2, width = 20)

# Number Buttons created. self.b1 = object, tkinter.button calls button module, command = do1 will\

# become a method.

self.b1 = tkinter.Button(self.no123Frame, width = 3 , text = '1', command = self.do1)

self.b2 = tkinter.Button(self.no123Frame, width = 3 , text = '2', command = self.do2)

self.b3 = tkinter.Button(self.no123Frame, width = 3 , text = '3', command = self.do3)

self.b4 = tkinter.Button(self.no456Frame, width = 3 , text = '4', command = self.do4)

self.b5 = tkinter.Button(self.no456Frame, width = 3 , text = '5', command = self.do5)

self.b6 = tkinter.Button(self.no456Frame, width = 3 , text = '6', command = self.do6)

self.b7 = tkinter.Button(self.no789Frame, width = 3 , text = '7', command = self.do7)

self.b8 = tkinter.Button(self.no789Frame, width = 3 , text = '8', command = self.do8)

self.b9 = tkinter.Button(self.no789Frame, width = 3 , text = '9', command = self.do9)

self.b0 = tkinter.Button(self.no0DFrame, width = 3 , text = '0', command = self.do0)

self.bD = tkinter.Button(self.no0DFrame, width = 3 , text = '.', command = self.doD)

self.bCal = tkinter.Button(self.no0DFrame, width = 3 , text = '=', command = self.cal)

# Operators created

self.bAdd = tkinter.Button(self.optsFrame, width = 5, text = '+', command = self.add)

self.bSub = tkinter.Button(self.optsFrame, width = 5, text = '-', command = self.sub)

self.bMul = tkinter.Button(self.optsFrame, width = 5, text = '*', command = self.mul)

self.bDiv = tkinter.Button(self.optsFrame, width = 5, text = '/', command = self.div)

self.bMod = tkinter.Button(self.optsFrame, width = 5, text = '%', command = self.mod)

self.bClr = tkinter.Button(self.topFrame, width = 5, text = 'Clear', command = self.clr)

# Create numbers. op1 = operand, op2 = operator

op1 = 0.0

op2 = 0.0

opt = ''

def organizeInterface(self):

# Method pack object(assembling display label into window).

# Order of packing will be the order the labels will display.

self.display.pack(side = 'left')

self.bClr.pack()

self.topFrame.pack()

self.b1.pack(side = 'left')

self.b2.pack(side = 'left')

self.b3.pack(side = 'left')

self.no123Frame.pack()

self.b4.pack(side = 'left')

self.b5.pack(side = 'left')

self.b6.pack(side = 'left')

self.no456Frame.pack()

self.b7.pack(side = 'left')

self.b8.pack(side = 'left')

self.b9.pack(side = 'left')

self.no789Frame.pack()

self.bD.pack(side = 'left')

self.b0.pack(side = 'left')

self.bCal.pack(side = 'left')

self.no0DFrame.pack(side = 'left')

self.numbersFrame.pack(side = 'left')

self.bAdd.pack(side = 'left')

self.bSub.pack(side = 'left')

self.bDiv.pack(side = 'left')

self.bMul.pack(side = 'left')

self.bMod.pack(side = 'left')

self.optsFrame.pack()

self.bottomFrame.pack()

def runInterface(self):

tkinter.mainloop()

#clear user input.

def clear(self):

self.op1 = 0.0

self.op2 = 0.0

self.opt = ''

# Set user input, set variable self.n.set then self.n.get will append and concatonate.

def do1(self):

self.n.set(self.n.get()+'1')

def do2(self):

self.n.set(self.n.get()+'2')

def do3(self):

self.n.set(self.n.get()+'3')

def do4(self):

self.n.set(self.n.get()+'4')

def do5(self):

self.n.set(self.n.get()+'5')

def do6(self):

self.n.set(self.n.get()+'6')

def do7(self):

self.n.set(self.n.get()+'7')

def do8(self):

self.n.set(self.n.get()+'8')

def do9(self):

self.n.set(self.n.get()+'9')

def do0(self):

self.n.set(self.n.get()+'0')

def doD(self):

self.n.set(self.n.get()+'.')

# record operator = self.opt and get first number entry = self.n.get().

# need to clean up the label of the first number entry before getting next \

# entry of numbers.

def add(self):

self.opt = '+'

self.op1 = float(self.n.get())

self.n.set('')

#to get calculator to see negative number verse \

#subtraction create if statement for empty string.

def sub(self):

if self.n.get() == '':

self.n.set('-')

else:

self.opt = '-'

self.op1 = float(self.n.get())

self.n.set('')

def mul(self):

self.opt = '*'

self.op1 = float(self.n.get())

self.n.set('')

def div(self):

self.opt = '/'

self.op1 = float(self.n.get())

self.n.set('')

def mod(self):

self.opt = '%'

self.op1 = float(self.n.get())

self.n.set('')

# clear set to clr button to clean label

def clr(self):

self.clear()

self.n.set('')

# Call calculate method to get calculations and write if statements \

# to define what operator user wanted.

def cal(self):

self.op2 = float(self.n.get())

if self.opt == '+':

self.n.set(self.op1 + self.op2)

elif self.opt == '-':

self.n.set(self.op1 - self.op2)

elif self.opt == '*':

self.n.set(self.op1 * self.op2)

elif self.opt == '/':

self.n.set(self.op1 / self.op2)

elif self.opt == '%':

self.n.set(self.op1 % self.op2)

class BetterCalculator(Calculator):

def __init__(self):

Calculator.__init__(self)

self.uOptsFrame = tkinter.Frame(self.bottomFrame)

self.bLog = tkinter.Button(self.uOptsFrame, width = 5, text = 'log', command = self.log)

self.bPct = tkinter.Button(self.uOptsFrame, width = 5, text = 'Pct', command = self.pct)

self.bSqrt = tkinter.Button(self.uOptsFrame, width = 5, text = 'Sqrt', command = self.sqrt)

self.bPow = tkinter.Button(self.optsFrame, width = 5, text = 'pow', command = self.pow)

def reorganizeInterface(self):

self.bClr.configure(bg = 'red')

self.bAdd.configure(bg = 'yellow')

self.bSub.configure(bg = 'yellow')

self.bMul.configure(bg = 'yellow')

self.bDiv.configure(bg = 'yellow')

self.bMod.configure(bg = 'yellow')

self.bCal.configure(bg = 'green')

Calculator.organizeInterface(self)

self.bLog.pack()

self.bPct.pack()

self.bSqrt.pack()

self.bPow.pack()

self.uOptsFrame.pack(side='left')

def log(self):

self.op1 = float(self.n.get())

self.n.set(math.log(self.op1))

def pct(self):

self.op1 = float(self.n.get())

self.n.set(self.op1 * 100)

def sqrt(self):

self.op1 = float(self.n.get())

self.n.set(math.sqrt(self.op1))

def pow(self):

self.opt = 'pow'

self.op1 = float(self.n.get())

self.n.set = ('')

def cal(self):

Calculator.cal(self)

if self.opt == 'pow':

self.n.set(self.op1 ** self.op2)

this is a separate file for the driver of this program to make it run:

import calculator

import math

def main():

myCal = calculator.BetterCalculator()

myCal.reorganizeInterface()

myCal.runInterface()

main()

网友答案:

Without looking at the rest of the code, I see an obvious typo / brain-o in pow:

def pow(self):
    self.opt = 'pow'
    self.op1 = float(self.n.get())
    self.n.set = ('')

That last line should be:

    self.n.set('')

without the = part, so as to call self.n.set, not to replace the function with a string. (Replacing the function with a string will cause a later attempt to call self.n.set to produce the error you saw.)

网友答案:

Look at your pow() method

self.n.set = ('')

It's definitely is a typo. Replace with

self.n.set('')
分享给朋友:
您可能感兴趣的文章:
随机阅读: