我正在创建Python tkinter程序,访问用户输入值。然后,用户将从单选按钮中选择包括华氏度或摄氏度的选项。将显示消息显示用户选择的选项,按下计算按钮时,新的转换的华氏度或摄氏值将显示在计算按钮后面的标签上。 我构建了基于View Model Control的程序,当我执行主程序时,我已经跟踪错误:
AttributeError: 'Calculate' object has no attribute 'radioButtonShowChoice'
我有3个独立的文件,用于View Model Control架构 第一个被命名为视图框架:
import tkinter
class AppFrame(tkinter.Frame):
"""
class AppFrame is the View for a simple program converts between temperature
in Fareinheit and tempterature in Celicus
"""
def __init__(self, controller):
tkinter.Frame.__init__(self) # initializes the superclass
self.pack() # required in order for the Buttons to show up properly
self.controller = controller
v = tkinter.IntVar()
self.titleLabel1 = tkinter.Label(self)
self.titleLabel1["text"] = "Fahrenheit and Celcius converter program"
self.titleLabel1.pack()
self.titleLabel2 = tkinter.Label(self)
self.titleLabel2["text"] = "Enter your value here:"
self.titleLabel2.pack({"fill":"x","padx":"10"})
self.entryData = tkinter.Entry(self)
self.entryData.pack({"fill":"x","padx":"10"})
self.titleLabel3 = tkinter.Label(self)
self.titleLabel3["text"] = "Choose options bellow:"
self.titleLabel3.pack({"fill":"x","padx":"10"})
self.radioButton1 = tkinter.Radiobutton(self,text="Fahreinheit", variable = v, value =1 )
self.radioButton1["command"] = self.controller.radioButtonShowChoice
self.radioButton1.pack({"anchor":"w"})
self.radioButton2 = tkinter.Radiobutton(self,text="Celcius", variable = v, value = 2)
self.radioButton2["command"] = self.controller.radioButtonShowChoice
self.radioButton2.pack({"anchor":"w"})
self.resultLabel1 = tkinter.Label(self)
self.titleLabel1.pack({"fill":"x","padx":"10"})
self.calculateButton = tkinter.Button(self)
self.calculateButton["text"] = "CALCULATE"
self.calculateButton["command"] = self.controller.buttonCalculate
self.calculateButton.pack({"fill":"x","padx":"10"})
self.resultLabel2 = tkinter.Label(self)
self.titleLabel2.pack({"fill":"x","padx":"10"})
第二个被命名为模型计算
import tkinter
import frame
class Calculate:
"""
Class Calculate is the Model for calculating the convert to Fahreinheit or Celcius
It also displays the result on the screen
"""
def __init__(self):
self.newValue = 0
self.view = frame.AppFrame(self)
def displayChoice(self):
if str(self.view.v.get()) == "1":
return "You chose option 1 for Fahreinheit converter"
elif str(self.view.v.get()) == "2":
return "You chose option 2 for Celcius converter"
def displayResult(self):
if str(self.view.v.get()) == "1":
self.newValue = (9/5 * int(self.view.entryData.get())) + 32
elif str(self.view.v.get()) == "2":
self.newValue = 5/9 * (int(self.view.entryData.get()) - 32)
def __str__(self):
return str(self.newValue)
最后一个是主程序,名为myMain for Controller
import tkinter
import frame
import calculate
class Display:
"""
The Display class for an app that follows the Model/View/Controller architecture.
When the user presses the Button converter on the View, this Display calles the appropriate methods in the Model.
"""
def __init__(self):
root = tkinter.Tk()
self.model = calculate.Calculate()
self.view = frame.AppFrame(self)
self.view.mainloop()
root.destroy()
def radioButtonShowChoice(self):
self.view.resultlabel1["text"] = self.model.displayChoice
def buttonCalculate(self):
self.model.displayResult()
self.view.resultLabel2["text"] = "The new value of tempreature is "+str(self.model
if __name__ == "__main__":
d = Display()
任何帮助使这个程序工作将不胜感激 感谢
答案 0 :(得分:1)
在Display.__init__(self)
self.model = calculate.Calculate()
在Calculate.__init__(self)
self.view = frame.AppFrame(self)
在AppFrame.__init__(self, controller)
self.controller = controller
...
self.radioButton1["command"] = self.controller.radioButtonShowChoice
self.radioButton2["command"] = self.controller.radioButtonShowChoice
self.controller
是传递给AppFrame
构造函数的值,它是一个Calculate对象。您正尝试分配radioButtonShowChoice
,Calculate
不是Display
中的属性,如错误消息所示。我假设您要从AppFrame
分配函数。您还创建了两个让我感到困惑的Calculate
- 一个在Display
对象中,另一个在AppFrame
个对象中。
在您的实施中,Display
需要AppFrame
中的函数,因此Display
在某些时候需要引用Calculate - AppFrame instance #1
Display - AppFrame instance #2, Calculate object
AppFrame #1 - Calculate as the controller
AppFrame #2 - Display as the controller
- 从计算内部创建的第一个函数不会有这个参考。
{{1}}
最后,带错误消息的地方应该是一个堆栈跟踪,指向发生错误的行号。那真的很重要。