Python温度转换MVC样式:为什么我得到“TypeError:buttonPressed()缺少1个必需的位置参数:'self'”

2024-09-30 04:34:10 发布

您现在位置:Python中文网/ 问答频道 /正文

新手想成为这里的python程序员。我有一个家庭作业(我没法完成),现在下课了,我很乐意在这里寻求帮助。我仍然很好奇这个错误和我做错了什么。。。我确信这与控制器和视图如何相互引用有关,但我无法理解这个错误。我已经被困在这上面三天了。我真的需要帮助-因为我真的想了解python和MVC。在

有关上下文,请参阅下面的屏幕标题。在

错误:

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'

视图:我的框架.py在

^{pr2}$

型号:计数器.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)

控制器:“胶水.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个信誉的帖子。在

编辑: 在修复了self-ref循环之后,我遇到了其他问题,如下所示: Python MVC architecture Temperature Conversion: Why am I getting "NameError: global name 'view' is not defined"


Tags: andthetoinselfviewmodelthat
1条回答
网友
1楼 · 发布于 2024-09-30 04:34:10

MyFrame.__init__中,保存对Controller类的引用:

self.controller = glue.Controller

但实际上并没有创建Controller的实例,这意味着Controller.__init__永远不会被调用。那可能不是你想做的。在

这也意味着当你这样做时:

^{pr2}$

你真的是说

    self.convertButton["command"]= glue.Controller.buttonPressed

这意味着您正在使一个unbound方法成为convertButton的回调。Unbound意味着该方法没有绑定到Controller的特定实例,这意味着self不会隐式传递给它,因此会出现错误。您的程序在启动时正在创建一个Controller实例,这就是所谓的MyFrame.__init__。实际上99%的方法都是正确的-您将Controller实例传递给MyFrame.__init__

    self.view = myFrame.MyFrame(self) #instantiates the VIEW

所以现在您只需将该实例分配给self.controller控制器。init`:

def __init__(self, controller):
    """
    places the controls on the frame
    """
    tkinter.Frame.__init__(self)
    self.pack()
    self.controller = controller  # NOT glue.Controller

相关问题 更多 >

    热门问题