Python温度转换MVC样式:为什么我得到"TypeError:buttonPressed()缺少1个必需的位置参数:'self''"的信息? [英] Python Temperature conversion MVC style: why am I getting "TypeError: buttonPressed() missing 1 required positional argument: 'self'"
问题描述
新手想在这里成为python程序员.我完成了一项家庭作业(无法完成),现在课程结束了,我很乐意在这里寻求帮助.我仍然对这个错误以及我在做什么错感到非常好奇...我确定这与CONTROLLER和VIEW如何相互引用有关,但是我这个错误超出了我的理解.我已经坚持了大约三天.我真的可以使用帮助-因为我真的想了解python和MVC.
newbie-wanna-be python-programmer here. I had a homework assignment (that I couldn't get) and now that the class is over, I feel comfortable asking for help here. I'm still really curious about this error and what I'm doing wrong... I'm sure it's related to how the CONTROLLER and the VIEW are referring to each other, but I this error is beyond my understanding. I've been stuck on this for about three days. I could really use help- because I really want to understand python and MVC.
有关上下文,请参见下面的屏幕截图.
Please see screen cap below for context.
错误:
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
VIEW: 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
MODEL: 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"
CONTROLLER: "glue.py"
import tkinter
import myFrame #the VIEW
import counter #the MODEL
class Controller:
"""
The CONTROLLER for an app that follows the MODEL/VIEW/CONTROLLER architecture.
When the user presses a button on the VIEW,
this controller calls the appropriate methods in the model.
The controller handles all the communication between the model and the view.
"""
def __init__(self):
"""
This starts the TK framework up;
instantiates the model;
instantiates the VIEW;
and states the event loop that waits for the user to press a button on the view
"""
root = tkinter.Tk() #This starts the TK framework up;
self.model = counter.Convert() #instantiates the model
self.view = myFrame.MyFrame(self) #instantiates the VIEW
self.view.mainloop() # states event loop waits for user to press button on view
root.destroy() #lets user quit
def buttonPressed(self):
"""
Convert F --> C
"""
self.model.convertTempF2C(self.view.fahrenheitEntrySpace.get)
#MODEL creates new celsius temp from(fahrenheit input)
self.view.celsiusEntrySpace.pop()
#replaces VIEW's old default celsius value
self.view.celsiusEntrySpace.insert(self.model.celsius)
#and insert's MODEL's newly converted (celsius) value
"""
Convert C --> F
"""
self.model.convertTempC2F(self.view.celsiusEntrySpace.get)
#MODEL creates new fahrenheit temp from (celsius input)
self.view.fahrenheitEntrySpace.pop()
#replaces VIEW's old default 0 fahrenheit value
self.view.fahrenheitEntrySpace.insert(self.model.fahrenheit)
#and insert's MODEL's newly converted (fahrenheit) value
if __name__=="__main__":
c = Controller()
屏幕截图
http://imgur.com/pAQc3Zw <-链接到屏幕截图(我可以不会发布10点声望.
screen cap
http://imgur.com/pAQc3Zw <-- link to screen cap (I can't post w/o 10 reputation.
修复self ref循环后,我遇到了其他问题,如下所示: Python MVC体系结构温度转换:为什么我要" NameError:未定义全局名称视图""
After fixing the self ref loop, I ran into other issues as seen here: Python MVC architecture Temperature Conversion: Why am I getting "NameError: global name 'view' is not defined"
推荐答案
在MyFrame.__init__
中,您正在保存对Controller
类的引用:
In MyFrame.__init__
, you're saving a reference to the Controller
class:
self.controller = glue.Controller
但是您实际上并不是在创建Controller
的实例,这意味着永远不会调用Controller.__init__
.那可能不是你的本意.
But you're not actually creating an instance of Controller
, which means Controller.__init__
is never called. That's probably not what you meant to do.
这也意味着您执行以下操作:
It also means that when you do this:
self.convertButton["command"]=self.controller.buttonPressed
你是真的在说
self.convertButton["command"]= glue.Controller.buttonPressed
这意味着您要使convertButton
的回调. Unbound表示该方法未绑定到Controller
的特定实例,这意味着self
不会隐式传递给它-因此会出现错误.您的程序在启动时正在创建一个Controller
实例,这就是所谓的MyFrame.__init__
.实际上,您已经99%地正确地完成了工作-您正在将Controller
实例传递给MyFrame.__init__
:
Which means you're making an unbound method the callback for convertButton
. Unbound means that the method isn't bound to a particular instance of Controller
, which means self
won't implicitly be passed to it - hence the error you're getting. Your program is creating a Controller
instance when it starts, and that is what's calling MyFrame.__init__
. You're actually 99% of the way to do things properly - you're passing the Controller
instance to MyFrame.__init__
:
self.view = myFrame.MyFrame(self) #instantiates the VIEW
所以现在您要做的就是将该实例分配给self.controller
Controller. init `:
So now all you need to do is assign that instance to 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
这篇关于Python温度转换MVC样式:为什么我得到"TypeError:buttonPressed()缺少1个必需的位置参数:'self''"的信息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!