Python温度转换MVC风格:为什么我得到;TypeError:buttonPressed()缺少1个必需的位置参数:';自我'&引用;
新手想成为这里的python程序员。我有一个家庭作业(我没能拿到),现在下课了,我很乐意在这里寻求帮助。我仍然很好奇这个错误和我做错了什么。。。我确信这与控制器和视图如何相互引用有关,但我无法理解这个错误。我已经被困在这三天了。我真的需要帮助——因为我真的想了解python和MVC 有关上下文,请参见下面的屏幕盖 错误:Python温度转换MVC风格:为什么我得到;TypeError:buttonPressed()缺少1个必需的位置参数:';自我'&引用;,python,tkinter,nameerror,Python,Tkinter,Nameerror,新手想成为这里的python程序员。我有一个家庭作业(我没能拿到),现在下课了,我很乐意在这里寻求帮助。我仍然很好奇这个错误和我做错了什么。。。我确信这与控制器和视图如何相互引用有关,但我无法理解这个错误。我已经被困在这三天了。我真的需要帮助——因为我真的想了解python和MVC 有关上下文,请参见下面的屏幕盖 错误: Exception in Tkinter callback Traceback (most recent call last): File "C:\Python33\lib
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1482, in __call__
return self.func(*args)
TypeError: buttonPressed() missing 1 required positional argument: 'self'
视图:myFrame.py
"""writing event handlers"""
import tkinter
import glue
class MyFrame(tkinter.Frame): #creates window for controls in an object made
#from a class called "tkinter.Frame"
"""
Class myFrame is a tkinter.Frame...
It contains two buttons, two entry areas, and four labels:
one button a converter;
one button quits the program;
one entry is for celsius;
one entry is for fahrenheit;
and the labels prompt user for input, and label the entry values as needed.
"""
def __init__(self, controller):
"""
places the controls on the frame
"""
tkinter.Frame.__init__(self) #initilizes the superclass
self.pack() #required for the buttons to show up properly.
self.controller = glue.Controller #saves ref to controller to call methods on
#contoller object when user generates events
#Fahrenheit Input Prompt
self.fahrenheitLabel = tkinter.Label(self)
self.fahrenheitLabel["text"] = ("Enter Fahrenheit Value:")
self.fahrenheitLabel.pack({"side":"left"})
#Fahrenheit Entry Space
self.fahrenheitEntrySpace = tkinter.Entry(self)
self.fahrenheitEntrySpace == self.fahrenheitEntrySpace.insert(1, "0")
self.fahrenheitEntrySpace.pack({"side":"left"})
#Fahrenheit Value label
self.fahrenheitLabel = tkinter.Label(self)
self.fahrenheitLabel["text"] = ("Fahrenheit Degrees")
self.fahrenheitLabel.pack({"side":"left"})
#Converter button
self.convertButton=tkinter.Button(self)
self.convertButton["text"]= "Convert"
self.convertButton["command"]=self.controller.buttonPressed
# an object that remembers both self and reply when later called
self.convertButton.pack({"side":"left"})
#Quit button
self.quitButton = tkinter.Button(self)
self.quitButton["text"] = "Press\nhere to\n***QUIT***"
self.quitButton["command"] = self.quit
#the statement above attaches the event handler
#self.quit() to the quit button
self.quitButton.pack({"side":"right"})
#Celsius Value label
self.celsiusLabel = tkinter.Label(self)
self.celsiusLabel["text"] = ("Celsius Degrees")
self.celsiusLabel.pack({"side":"right"})
#Celsius Entry Space
self.celsiusEntrySpace = tkinter.Entry(self)
self.celsiusEntrySpace["text"] == self.celsiusEntrySpace.insert(1, "0")
self.celsiusEntrySpace.pack({"side":"right"})
#Celsius Input Prompt
self.celsiusLabel = tkinter.Label(self)
self.celsiusLabel["text"] = ("Enter Celsius Value:")
self.celsiusLabel.pack({"side":"right"})
#Test program
if __name__=="__main__":
root = tkinter.Tk()
view = MyFrame() #puts the frame onto the user's screen.
view.mainloop()
root.destroy()
型号:counter.py
import tkinter
class Convert: #the MODEL
'''
class counter is the MODEL for a simple program that exemplifies
the MODEL/VIEW/CONTROLLER architecture.
It mostly just maintains two formulas that convert Fahrenheit to Celsius
and Celsius to Fahrenheit each time the f2C() or c2F methods are called.
in a real MVC app, the MODEL would contain all the business logic.
Note that the model never contains a reference to the VIEW.
'''
def __init__(self):
self.fahrenheitEntrySpace = 0
self.celsiusEntrySpace = 0
def convertTempF2C(self):
fahrenheit = fahrenheitEntrySpace.get()
if fahrenheit != 0.0:
celsius = (fahrenheit - 32) * 5 / 9
else:
celsius = -17.7777778
def convertTempC2F(self):
celsius = celsiusEntrySpace.get()
if celsius != 0.0:
fahrenheit = (celsius * 9.0/5.0 + 32)
else:
fahrenheit = 32
def __str__(self):
return str(self.counter)
控制器:“glue.py”
纱帽
在
MyFrame.\uuuuu init\uuuu
中,您正在保存对控制器
类的引用:
self.controller = glue.Controller
但实际上您并没有创建Controller
的实例,这意味着Controller.\uuu init\uu
永远不会被调用。那可能不是你想做的
这还意味着,当您这样做时:
self.convertButton["command"]=self.controller.buttonPressed
你真的是说
self.convertButton["command"]= glue.Controller.buttonPressed
这意味着您正在使一个未绑定的方法成为convertButton
的回调。Unbound意味着该方法没有绑定到Controller
的特定实例,这意味着self
不会隐式地传递给它-因此会出现错误。程序启动时正在创建一个控制器
实例,这就是调用MyFrame.\uuu init\uuu
。实际上,99%的操作方法都是正确的—您正在将控制器
实例传递给MyFrame
self.view = myFrame.MyFrame(self) #instantiates the VIEW
所以现在您需要做的就是将该实例分配给self.controller
controller.init`:
def __init__(self, controller):
"""
places the controls on the frame
"""
tkinter.Frame.__init__(self)
self.pack()
self.controller = controller # NOT glue.Controller
请稍等一下,我试过了。我不能发布关于缩进的错误消息,因为错误消息没有告诉我需要缩进哪个部分,我很难找到合适的部分-所以这是我找到的唯一方法,我可以实际发布。我糟糕的格式并不是因为疏忽——我只是无法以一种被接受的方式很好地格式化它。道歉!嗨,达诺!非常感谢您的反馈!那么,你是说我基本上只需要将self.controller=glue.controller替换为self.controller=glue.controller()?当我这么做的时候,事情变得有点疯狂。。。imgur.com/8a7gcxO@lilmookie啊,你有一个循环引用,Controller.\uu init\uu
创建一个MyFrame
的实例,MyFrame.\uu init``创建一个Controller的实例。因此,它们只是一次又一次地互相调用,直到达到递归极限。我很抱歉以前没有听到。奇怪的是,您几乎做到了这一点-您已经将
Controller`实例传递给了MyFrame.\uuuu init\uuuu
您只是没有使用它!这开始有意义了。我将myframe(视图)init从self.controller=Glue.controller()更改为self.controller=controller,现在我得到了对我更有意义的错误。我会看看我能做些什么,希望能发布一个完整的版本,供像我这样的人将来参考:p非常感谢你的帮助!我真的很感激!所讨论的(更好的)错误:Tkinter回调回溯中的异常(最近一次调用是最后一次):文件“C:\Python33\lib\Tkinter_init_uu2;.py”,第1482行,在call return self.func(*args)文件“C:\Users\Mike\Desktop\code\Assignment 6\glue.py”,第37行,在按钮按压的self.model.convertTempF2C(self.view.fahrenheitEntrySpace.get)中TypeError:convertTempF2C()接受1个位置参数,但给出了2个
def __init__(self, controller):
"""
places the controls on the frame
"""
tkinter.Frame.__init__(self)
self.pack()
self.controller = controller # NOT glue.Controller