Выполнение команды кнопки из другого файла?
Я начал работать над системой графического интерфейса, где мне нужно импортировать функцию из одного файла, которая будет выполняться в основном файле при нажатии кнопки, но каждый раз, когда я запускаю ее, я получаю:
AttributeError: partially initialized module 'Two' has no attribute 'sum'
(most likely due to a circular import)
Программа должна вводить два значения,
Value_a
и
Value_b
, а вызываемая функция должна складывать их и выводить результат в новом окне. Вот пример файла, который я хочу импортировать, и его функции.
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()
Когда это запускается, я получаю указанную выше ошибку.
2 ответа
Проблема в том, что у вас действительно есть циркуляр. Модуль импортирует модуль, который импортирует модуль ... и т. Д. Однако предложенного простого исправления @acw1668 недостаточно, чтобы исправить ситуацию, потому что модуль ссылается не только на
Window
атрибут модуля. Мое решение передает вещи в модуль
One
функция в модуле нуждается в аргументах (так что
Two
модулю не нужно
import
чтобы получить к ним доступ).
Другая проблема с вашим кодом tkinter обсуждается в вопросе Tkinter: AttributeError: объект NoneType не имеет атрибута , который я предлагаю вам прочитать.
Ниже приведены изменения в обоих ваших модулях, которые устраняют все эти проблемы.
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_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)
(Вот еще один ответ, который очень похож на то, что я изначально получил в другом ответе, прежде чем сделать что-то, что, как мне казалось, было проще. Я отправляю его как отдельный ответ, потому что оказывается, что идея модуля, получающего ссылку на себя, была в течение очень долгого времени , так что это не так уж странно или хакерски, как я первоначально думал.)
Проблема в том, что у вас действительно есть циркуляр. Модуль импортирует модуль, который импортирует модуль ... и т. Д. Однако предложенного простого исправления @acw1668 недостаточно, чтобы исправить ситуацию, потому что модуль ссылается не только на
Window
атрибут модуля. Мое решение проходит целиком
One
модуль к функции в качестве аргумента (так что модулю не нужно
import
чтобы получить доступ к его атрибутам).
Другая проблема с вашим кодом tkinter обсуждается в вопросе Tkinter: AttributeError: объект NoneType не имеет атрибута , который я предлагаю вам прочитать.
Ниже приведены изменения в обоих ваших модулях, которые устраняют все эти проблемы. Чтобы избежать циклического импорта, команда Button теперь передает вызывающий модуль в качестве аргумента в
sum()
функция в модуле
Two
. Хотя делать что - то вроде этого является несколько необычным, на самом деле является очень логичным , если вы думаете об этом (и хотите , чтобы избежать круговой import`).
One.py
:
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()
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, text= str(c)).grid(row=1, column=0)