Python将类移动到单独的文件会导致nameError

时间:2018-07-06 05:52:46

标签: python tkinter import nameerror

我只是想将ScreenThree类移到一个单独的文件9中,我很快将有更多文件)。...但是对于lambda,我会遇到nameError ...如何解决?

我尝试了许多安排,但始终会遇到某种nameError的情况。对于这篇文章,我删除了ScreenTwo,因为这些基本上看起来都一样。 将此类移至其自己的文件时,需要更改什么?我使用了导入,这似乎可以正常工作并显示在screen3上。 ,但是按钮lambda是失败的地方         将tkinter导入为tk

LARGE_FONT = ("Verdana", 12) # font's family is Verdana, font's size is 12 

class MainWindow(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.title("Fuzzy System") # set the title of the main window
        self.geometry("300x300") # set size of the main window to 300x300 pixels

        # this container contains all the screens
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)   # make the cell in grid cover the entire window
        container.grid_columnconfigure(0,weight=1) # make the cell in grid cover the entire window
        self.frames = {} # these are screens we want to navigate to

        for F in (ScreenOne, ScreenTwo,ScreenThree): # for each screen
            frame = F(container, self) # create the screen
            self.frames[F] = frame  # store into frames
            frame.grid(row=0, column=0, sticky="nsew") # grid it to container

        self.show_frame(ScreenOne) # let the first screen is ScreenOne

    def show_frame(self, name):
        frame = self.frames[name]
        frame.tkraise()

class ScreenOne(tk.Frame):
    def __init__(self, parent, controller):
        self.controller=controller
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text='This is ScreenOne', font=LARGE_FONT)
        label.pack(pady=10, padx=10) # center alignment
   # when click on this button, call the show_frame method to make screenOne appear
        button1 = tk.Button(self, text='Visit screen two', command=lambda : controller.show_frame(ScreenTwo))
        button1.pack() # pack it in
        self.button2 = tk.Button(self, text='GOTO Screen Three', command=lambda : controller.show_frame(ScreenThree))
        self.button2.place(relx=0.5, rely=0.29, height=41, width=144)
        self.button2.configure(background="#911218")

class ScreenThree(tk.Frame):
    def __init__(self, parent, controller):
        self.controller=controller
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text='This is screen Three', font=LARGE_FONT)
        label.pack(pady=10, padx=10)

        button1 = tk.Button(self, text='GOTO ScreenTwo', command=lambda : controller.show_frame(ScreenTwo))
        button1.pack()
        button2 = tk.Button(self, text='GOTO Screen One', command=lambda : controller.show_frame(ScreenOne))
        button2.pack()

if __name__ == '__main__':
    app = MainWindow()
    app.mainloop()


I have several classes, all looking similar to the following. They all work fine, no problems. However I want to move them to individual files, since they will soon become lengthy. I moved the following to file `scr3.py`.  
I then added the following to my main file:

    from scr3 import ScreenThree

Screen one and two work fine and my buttons in `screen3` show up.  However when pushing on the screen three buttons I get a `NameError: name 'ScreenOne' is not defined` and similar for `screen2` (see the lambda funcs).  These worked fine when all was in one file.  `Screen1` and `2` (still in the `main` file) continue to work fine.  
Why does it work fine when this same code is in the `main` file , but now fails? It has only been moved.  What is the workaround?

    import tkinter as tk
    LARGE_FONT = ("Verdana", 12) # font's family is Verdana, font's size is 12

    class ScreenThree(tk.Frame):

    def __init__(self, parent, controller):
        self.controller=controller
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text='This is screen Three', font=LARGE_FONT)
        label.pack(pady=10, padx=10)

        button1 = tk.Button(self, text='GOTO ScreenTwo', command=lambda : controller.show_frame(ScreenTwo))
        button1.pack()
        button2 = tk.Button(self, text='GOTO Screen One', command=lambda : controller.show_frame(ScreenOne))
        button2.pack()

1 个答案:

答案 0 :(得分:0)

ScreenThree的代码不再与例如ScreenOne。您可以通过传递对ScreenOneScreenTwo的引用作为__init__的参数来解决此问题。