2013-08-04 2 views
0

Итак, я должен сделать базовый калькулятор, используя графический интерфейс в python. Я выполнил эту задачу со всеми работающими кнопками. Теперь для шага 2 я должен наследовать исходный класс калькулятора и создать новый класс под названием BetterCalculator, который добавляет в кнопки sqrt, log, pct и pow. У меня все работает для кнопки ПР, за исключением, и когда я запускаю программу с тем, что учитель называет водитель, я получаю эту ошибку:python GUI TypeError: объект 'str' не может быть вызван

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 

и вот мой код:

#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) 

это это отдельный файл для водителя этой программы, чтобы сделать его запустить:

import calculator 
import math 

def main(): 

    myCal = calculator.BetterCalculator() 

    myCal.reorganizeInterface() 
    myCal.runInterface() 


main() 

ответ

1

Посмотрите на ваш метод pow()

self.n.set = ('') 

Это определенно опечатка. Заменить

self.n.set('') 
2

Не смотря на остальной части кода, я вижу очевидную опечатка/мозг-о в pow:

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

Последняя строка должна быть:

self.n.set('') 

без части =, чтобы вызвать self.n.set, чтобы не заменить функцию на строку. (Замена функции строкой приведет к более поздней попытке вызвать self.n.set для получения ошибки, которую вы видели.)