Я разделил свое приложение tkinter на несколько файлов, и сейчас у меня есть два файла:
Main.py
import tkinter as tk
from login_info import LoginInfo
class Main(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.login_page = LoginInfo(self)
self.login_page.pack(expand='True')
if __name__ == "__main__":
root = tk.Tk()
Main(root).pack(side = "top", fill = "both", expand=True)
root.mainloop()
Login_page.py
import tkinter as tk
class LoginInfo(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.login_frame = tk.Frame(self)
self.login_frame.pack()
self.username_label = tk.Label(self.login_frame, text='Username:')
self.username_label.grid(row=0, column=0, padx=(10,0), pady=(10,0))
self.username_entry = tk.Entry(self.login_frame)
self.username_entry.grid(row=0, column=1, padx=(10,0), pady=(10,0))
self.password_label = tk.Label(self.login_frame, text='Password:')
self.password_label.grid(row=1, column=0, padx=(10,0), pady=(10,0))
self.password_entry = tk.Entry(self.login_frame)
self.password_entry.grid(row=1, column=1, padx=(10,0), pady=(10,0))
self.login_button = tk.Button(self.login_frame, text='Login', command=self.login)
self.login_button.grid(row=2, column=0, columnspan=2, pady=20)
root.bind('<Return>', self.login)
def login(self,event):
print('Logged In')
if __name__ == "__main__":
root = tk.Tk()
LoginInfo(root).pack(side = "top", fill = "both", expand=True)
root.mainloop()
На странице входа я пытаюсь связать кнопку возврата с функцией, но получаю эту ошибку:
NameError: name 'root' is not defined
Это происходит, только если я запускаю код из main.py, если я запускаю его из login_page.py, он работает
Удалите дубли...
if __name__ == "__main__":
root = tk.Tk()
LoginInfo(root).pack(side = "top", fill = "both", expand=True)
root.mainloop()
... из login_page.py и запустить код из main.py.
Используйте if __name__ == '__main__':... только один раз и только в модуле, который запускает программу. Потому что только в этом модуле специальная переменная __main__ будет иметь значение '__main__'.
Кроме того, убедитесь, что вы импортируете из login_page, а не из login_info в main.py, как вы назвали этот модуль login_page.py, а не login_info.py.
Я смог запустить ваш пример, выполнив следующие действия:
# main.py
import tkinter as tk
from login_page import LoginPage
class Main(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.login_page = LoginPage(self)
self.login_page.pack(expand='True')
if __name__ == "__main__":
root = tk.Tk()
main = Main(root)
main.pack(side = "top", fill = "both", expand=True)
root.mainloop()
# login_page.py
import tkinter as tk
class LoginPage(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.login_frame = tk.Frame(self)
self.login_frame.pack()
self.username_label = tk.Label(self.login_frame, text='Username:')
self.username_label.grid(row=0, column=0, padx=(10,0), pady=(10,0))
self.username_entry = tk.Entry(self.login_frame)
self.username_entry.grid(row=0, column=1, padx=(10,0), pady=(10,0))
self.password_label = tk.Label(self.login_frame, text='Password:')
self.password_label.grid(row=1, column=0, padx=(10,0), pady=(10,0))
self.password_entry = tk.Entry(self.login_frame)
self.password_entry.grid(row=1, column=1, padx=(10,0), pady=(10,0))
self.login_button = tk.Button(self.login_frame, text='Login', command=self.login)
self.login_button.grid(row=2, column=0, columnspan=2, pady=20)
self.bind_all('<Return>', self.login)
def login(self, event=None):
print('Logged In')
Хитрость заключается в том, чтобы использовать self.bind_all вместо root.bind в нижней части login_page.py, что привязывает ключ ко всему приложению. Эта функция, похоже, не задокументирована в официальных документах Python tkinter , что может указывать на то, что существует более питоническое решение.
Я лично предпочел бы поместить объявление об этой привязке в файл main.py. Здесь у нас есть подчиненный модуль, который молча модифицирует родительский модуль. Чем больше становится проект, тем больше это приводит к проблемам.
Обратите внимание, что self.login() используются опцией command кнопки и bind(), поэтому аргумент event должен быть необязательным. В противном случае, когда он вызывается нажатием кнопки, будет возбуждено исключение.
Просто измените def login(self, event) на def login(self, event=None), если аргумент event не используется внутри функции.
Что ты хочешь делать на линии root.bind('<Return>', self.login)? Когда login_page.py импортируется, root не определяется в модуле.