从另一个文件执行 Button 命令?

问题描述

我已经开始在 GUI 系统上工作,我需要从一个文件中导入一个函数,以便在按下按钮时在主文件中执行,但每次运行它时我都会得到:

AttributeError: partially initialized module 'Two' has no attribute 'sum'
  (most likely due to a circular import)

程序应该输入两个值,Value_aValue_b,被调用函数sum() 应该将这两个值相加并在新窗口中输出结果。这是我要导入的文件及其函数 sum() 的示例:

Two.py

from tkinter import *  #Import the tkinter module    
import One #This is the main file,One.py

def sum():
    newWindow = Toplevel(One.Window)
    newWindow.title("Sum")
    a = int(One.Value_a.get())
    b = int(One.Value_b.get())
    c = a+b
    Label(newWindow,text= str(c)).grid(row=1,column=0)

这是主文件的样子:

One.py

from tkinter import *
import Two

Window = Tk()
Window.title("Main Window")

Value_a = Entry(Window,width=15).grid(row=1,column=0)
Value_b = Entry(Window,width=15).grid(row=2,column=0)
my_button = Button(Window,text="Test",command=lambda: Two.sum).grid(row=3,column=0)

Window.mainloop()

运行时,我最终收到上述错误

解决方法

问题是因为您确实有一个循环 import。模块 One 导入模块 Two,它导入模块 One... 等等。但是,@acw1668 建议的简单修复不足以解决问题,因为 Two 模块引用了更多不仅仅是 Window 模块的 One 属性。我的解决方案传递模块 One 中的东西,模块 Two 中的函数需要作为参数(因此 Two 模块不需要 import 它来访问它们) .

问题 Tkinter: AttributeError: NoneType object has no attribute 中讨论了您的 tkinter 代码的另一个问题,我建议您阅读该问题。

以下是解决所有这些问题的两个模块的更改。

One.py

from tkinter import *
import Two


Window = Tk()
Window.title("Main Window")

Value_a = Entry(Window,width=15)
Value_a.grid(row=1,column=0)
Value_b = Entry(Window,width=15)
Value_b.grid(row=2,column=0)

my_button = Button(Window,text="Test",command=lambda: Two.sum(Window,Value_a,Value_b))
my_button.grid(row=3,column=0)

Window.mainloop()

Two.py

from tkinter import *


def sum(Window,Value_b):
    newWindow = Toplevel(Window)
    newWindow.title("Sum")
    a = int(Value_a.get())
    b = int(Value_b.get())
    c = a+b
    Label(newWindow,text= str(c)).grid(row=1,column=0)
,

(这是另一个答案,它与我在做一些我觉得更简单的事情之前最初在我的另一个答案中的答案非常相似。我将其作为单独的答案发布,因为事实证明 {{ 3}},所以这样做并没有我最初想的那么奇怪或那么骇人听闻。)

问题是因为您确实有一个循环 import。模块 One 导入模块 Two,它导入模块 One... 等等。但是,@acw1668 建议的简单修复不足以解决问题,因为 Two 模块引用了更多不仅仅是 Window 模块的 One 属性。我的解决方案将 whole One 模块作为参数传递给函数(因此 Two 模块不需要 import 它来访问其属性).

问题 idea of a module getting a reference to itself has been around for a very long time 中讨论了您的 tkinter 代码的另一个问题,我建议您阅读该问题。

以下是解决所有这些问题的两个模块的更改。为了避免循环导入,Button 命令现在将调用模块作为参数传递给模块 sum() 中的 Two 函数。虽然做这样的事情有点不寻常,但如果你仔细想想,实际上是非常合乎逻辑的(并且想要避免循环导入`)。

One.py

from tkinter import *
import Two

CURRENT_MODULE = __import__(__name__)

Window = Tk()
Window.title("Main Window")

Value_a = Entry(Window,command=lambda: Two.sum(CURRENT_MODULE))
my_button.grid(row=3,column=0)

Window.mainloop()

Two.py

from tkinter import *

def sum(One):
    newWindow = Toplevel(One.Window)
    newWindow.title("Sum")
    a = int(One.Value_a.get())
    b = int(One.Value_b.get())
    c = a+b
    Label(newWindow,column=0)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...