尝试在不同类的函数中调用类的实例时,Python 中出现名称错误

问题描述 投票:0回答:1

我目前正在编写一个简单的应用程序,其目的是指导用户完成礼品包装定制过程。

下面是我创建 tkinter 窗口的方式,以及我设置框架控制器的方式:

class GuiController(tk.Tk):
    def __init__(self, *args, **kwargs):
         
        "added all parameters here"

# this dictionary contains all the existing pages of the GUI
        self.frames = {}

# the available pages are iterated through a for loop so to:
        for F in (HomePage, ShapePg, DimensionPg, WrappingPaperPg):
            # create an instance of each class
            frame = F(self.main_frame, self)
            # place them inside the dictionary
            self.frames[F] = frame
            frame.grid(row=1, column=0, sticky='nsew')
            frame.config(height=550, width=1000, bg="#EBFFFE")

我决定采用 VCM 模式,因此对于每个页面我都创建了一个控制器来处理数据的收集(我最终将其传递到相应的模块)。

DimensionPg 负责收集礼物尺寸,并为每个形状设置不同的框架(因为每个形状都需要不同的尺寸) 将显示哪个框架由用户在 ShapePg 内通过选择礼物的形状(立方体、长方体或圆柱体)来决定

因此,当单击其中一个形状按钮时,它将调用相关控制器(我将其放置在字典中),如下所示:

 cube_button = tk.Button(self, text="Cube", command=lambda:    controllers.get("CubeController").set_dimension()

控制器的目的是调用 DimensionPg 必须执行的正确设置方法:

class CubeController(ShapeController):

    def set_dimension(self):
        app.frames.get(DimensionPg).cube_setup()

这就是问题发生的地方:我已经像这样实例化了 GUI 控制器:

if __name__ == "__main__":
    app = GuiController()
    app.mainloop()

所以 set_dimension 的目的是:

  1. 查找应用程序
  2. 查看框架内部{}
  3. 找到尺寸Pg
  4. 最后调用setup方法。

现在,在这个阶段,我的代码不会显示任何错误或警告,最重要的是,当我将鼠标悬停在“app.frames.get(DimensionPg).cube_setup()”的每个元素上时,相应的元素也会突出显示(这让我认为 python 确实了解该去哪里)。

到目前为止一切似乎都很好,但是当我执行代码时,它最终会导致: “名称错误:找不到名称“应用程序””。

我尝试调整我构造 set_dimensions() 的方式,但任何与上面稍有不同的内容都会立即导致一堆错误或警告。

我不知道为什么它找不到它,而且考虑到代码甚至没有抛出任何可能引导我到某个地方的错误或警告,我不知道从这里该去哪里

python tkinter nameerror
1个回答
0
投票
问题是由于

app

 类的 
set_dimension
 方法中的变量 
CubeController
 是局部变量,而定义为 
app
 类的对象的变量 
GuiController
 是一个全局变量。所以这两个
app
实际上是两个不同的变量,这就是为什么你会遇到
NameError
app
实际上并不是在
set_dimension
方法的范围内定义的,所以当引用
app
时在该方法中,它实际上并不存在于该范围内,因此 
NameError

要解决此问题,您可以尝试以下方法(不保证这会起作用,因为我自己没有测试过,这只是我认为可能有效的方法。希望它可以正常工作。):

首先,修改

set_dimension

 类中的 
CubeController
 方法,如下所示:

class CubeController(ShapeController): def set_dimension(self, app): app.frames.get(DimensionPg).cube_setup()
然后修改

cube_button

变量如下:

cube_button = tk.Button(self, text="Cube", command=lambda: controllers.get("CubeController").set_dimension(self)
    
© www.soinside.com 2019 - 2024. All rights reserved.