Python 从另一个文件执行按钮命令?

Python 从另一个文件执行按钮命令?,python,tkinter,tkinter-button,Python,Tkinter,Tkinter Button,我已经开始在GUI系统上工作,在该系统中,当按下按钮时,我需要从一个文件导入要在主文件中执行的函数,但每次运行时,我都会得到: AttributeError: partially initialized module 'Two' has no attribute 'sum' (most likely due to a circular import) 程序应该输入两个值,Value\u a和Value\u b,被调用的函数sum()应该将这两个值相加,并在新窗口中输出结果。下面是我要导入的

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

AttributeError: partially initialized module 'Two' has no attribute 'sum'
  (most likely due to a circular import)
程序应该输入两个值,
Value\u a
Value\u 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)
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()
这是主文件的外观:

One.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)
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()

当运行此命令时,我最终得到了上述错误。

问题在于您确实有一个循环
导入。模块
One
导入模块
Two
哪个模块导入模块
One
。。。但是@acw1668建议的简单修复不足以修复问题,因为
Two
模块引用的不仅仅是
One
模块的
窗口
属性。我的解决方案将模块
One
中的内容传递给模块
Two
中的函数作为参数(因此
Two
模块不需要
导入它来访问它们)

问题中讨论了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()
from tkinter import *


def sum(Window, Value_a, 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)
from tkinter import *
import Two

CURRENT_MODULE = __import__(__name__)

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(CURRENT_MODULE))
my_button.grid(row=3, column=0)

Window.mainloop()
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, text= str(c)).grid(row=1, column=0)
Two.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()
from tkinter import *


def sum(Window, Value_a, 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)
from tkinter import *
import Two

CURRENT_MODULE = __import__(__name__)

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(CURRENT_MODULE))
my_button.grid(row=3, column=0)

Window.mainloop()
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, text= str(c)).grid(row=1, column=0)
(这是另一个答案,与我最初在做一些我觉得更简单的事情之前的另一个答案非常相似。我将其作为单独的答案发布,因为事实证明,这样做并不像我最初认为的那么奇怪或太过刻薄。)


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

问题中讨论了tkinter代码的另一个问题,我建议您阅读

下面是对两个模块的更改,它们修复了所有这些问题。为了避免循环导入,Button命令现在将调用模块作为参数传递给module
Two
中的
sum()
函数。虽然这样做有点不寻常,但如果您仔细想想(并且希望避免循环导入),实际上这是一个非常合乎逻辑的做法

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()
from tkinter import *


def sum(Window, Value_a, 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)
from tkinter import *
import Two

CURRENT_MODULE = __import__(__name__)

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(CURRENT_MODULE))
my_button.grid(row=3, column=0)

Window.mainloop()
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, text= str(c)).grid(row=1, column=0)
Two.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()
from tkinter import *


def sum(Window, Value_a, 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)
from tkinter import *
import Two

CURRENT_MODULE = __import__(__name__)

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(CURRENT_MODULE))
my_button.grid(row=3, column=0)

Window.mainloop()
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, text= str(c)).grid(row=1, column=0)

Two.py
内部导入
One
将创建另一个
Tk
One.Window
)的实例,在运行
One.py
时不使用
Tk
Window
)的实例。您需要将
Window
Value\u a
Value\u b
传递给
Two.sum()
,而不是在
Two.py
中导入
One
@acw1668:这并不那么容易。请参阅我发布的答案。我更喜欢在
One.py
中使用类,并将类的实例传递给
Two.sum()
@acw1668:这当然会起作用,但如果只将多个参数传递给
sum()
@acw1668:那就更简单了,因为它非常简单,我修改了我的答案,这样做-整个
sys.modules
方法太奇怪了…虽然它更简单,但如果以后
Two.sum()
需要引用另一个小部件,则需要更改函数定义。您最初的设计(或我建议使用类实例)不需要更改
Two.sum()
的定义,只需要更改函数的内容。@martineau:谢谢您的解决方案。由于您对代码进行了调整,程序按我的要求运行。谢谢