繁体   English   中英

Python:无法导入...(很可能是由于循环导入)

[英]Python: cannot import ... (most likely due to a circular import)

我正在尝试创建具有多个屏幕的简单应用程序。 这是我的项目结构。

 main.py
 - screens
     mainScreen.py
     regressions.py

我想要做的基本上是在它们之间切换,因为ImportError: cannot import name 'MainScreen' from partially initialized module 'screens.mainScreen' (most likely due to a circular import)我想我明白问题是什么,但我不知道如何克服它。

这是我的代码
主文件

import tkinter as tk
from screens.mainScreen import MainScreen

root = tk.Tk()

run = MainScreen(root)
root.mainloop()

回归.py

import tkinter as tk
from .mainScreen import MainScreen

class Regressions:

    def __init__(self, master):

        # keep `root` in `self.master`
        self.master = master

        self.label = tk.Button(self.master, text="Home", command=self.load_new)
        self.label.pack()

    def load_new(self):
        self.label.destroy()

        # use `root` with another class
        self.another = MainScreen(self.master)

主屏幕.py

import tkinter as tk
from .regressions import Regressions

class MainScreen:

    def __init__(self, master):

        # keep `root` in `self.master`
        self.master = master 

        self.label = tk.Button(self.master, text="Regressions", command=self.load_new)
        self.label.pack()

    def load_new(self):
        self.label.destroy()

        # use `root` with another class
        self.another = Regressions(self.master)

mainScreen.py 与regressions.py 相同,但重定向到regressions.py 我将感谢您提供如何解决它的任何提示。

正如错误消息中所述,问题是循环导入问题。

回归.py

from .mainScreen import MainScreen

主屏幕.py

from .regressions import Regressions

regressions导入mainScreenmainScreen导入regressions

您必须找到一种方法来消除这种依赖性。

也许这会有所帮助: 自定义包中的 Python 循环导入和init .py

您应该在导入模块之前使用if __name__=='__main__':以避免循环导入

回归.py

import tkinter as tk


if __name__=='__main__':
   from .mainScreen import MainScreen

class Regressions:

    def __init__(self, master):

        # keep `root` in `self.master`
        self.master = master

        self.label = tk.Button(self.master, text="Home", command=self.load_new)
        self.label.pack()

    def load_new(self):
        self.label.destroy()

        # use `root` with another class
        self.another = MainScreen(self.master)

主屏幕.py

import tkinter as tk

if __name__=='__main__':
   from .regressions import Regressions

class MainScreen:

    def __init__(self, master):

        # keep `root` in `self.master`
        self.master = master

        self.label = tk.Button(self.master, text="Regressions", command=self.load_new)
        self.label.pack()

    def load_new(self):
        self.label.destroy()

        # use `root` with another class
        self.another = Regressions(self.master)

顺便提一句:

这是 10 年前由 Bryan Oakley 创建的更复杂的版本。

在 tkinter 中的两帧之间切换

您可以在 Stackoverflow 上的许多问题中看到这种方法被重用。

我会以不同的方式组织它。

main.py我首先创建MainScreenRegressions ,然后将类分配给.another

然后,你就不必进口MainScreenregressions.pyRegressionsMainScreen.py因为所有它做main.py

# create screens
main_frame = MainScreen(root)
regressions_frame = Regressions(root)

# assing screens to other screens
main_frame.another = regressions_frame
regressions_frame.another = main_fram

但这可能需要不同的方法来显示它。

我会使用Frame创建屏幕,然后我可以使用.pack()在 window 中显示屏幕,并使用.pack_forget()从窗口中删除前一个屏幕。

这也是个好主意,因为它不会destroy屏幕,因此它具有所有旧值 - 因此,如果您再次显示相同的屏幕,那么您仍然具有旧值(在EntryCheckbox等中)并且Regressions可能仍会访问这些值在MainScreen ,并且MainScreen可以访问在Regressions

主屏幕.py

import tkinter as tk

class MainScreen(tk.Frame):

    def __init__(self, master):
        super().__init__(master)

        # keep `root` in `self.master`
        #self.master = master   # super().__init__(master) should do it automatically

        self.label = tk.Button(self, text="Regressions", command=self.load_new)
        self.label.pack()

        self.another = None

    def load_new(self):
        if self.another:
            # hide current screen (without destroying)
            self.pack_forget()
    
            # show another screen
            self.another.pack()

回归.py

import tkinter as tk

class Regressions(tk.Frame):

    def __init__(self, master):
        super().__init__(master)

        # keep `root` in `self.master`
        #self.master = master   # super().__init__(master) should do it automatically

        self.label = tk.Button(self, text="Home", command=self.load_new)
        self.label.pack()
        
        self.another = None

    def load_new(self):
        if self.another:
            # hide current screen (without destroying)
            self.pack_forget()
    
            # show another screen
            self.another.pack()

主文件

import tkinter as tk
from .mainScreen import MainScreen
from .regressions import Regressions

if __name__ == '__main__':
    root = tk.Tk()

    # create screens
    main_frame = MainScreen(root)
    regressions_frame = Regressions(root)

    # assing screens to other screens
    main_frame.another = regressions_frame
    regressions_frame.another = main_frame
    
    # show main_frame
    main_frame.pack()
    
    root.mainloop()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM