【发布时间】:2026-01-30 17:55:02
【问题描述】:
我正处于制作 GUI 的早期阶段。现在我有登录视图(LogInWind class)和注册视图(SignUpWind class)。当我只有一个视图时一切都很好,但现在我对这两个对象有循环依赖。这发生在按钮的命令中,因为在登录视图中有一个按钮可以将您带到注册视图,反之亦然。我想我可以为注册视图制作一个弹出窗口。但是我认为我切换窗口的方式是一种不好的做法,以后可能会带来更大的问题。
我的项目结构如下。
服务包将在 gui 和数据库之间建立连接。目前它什么也不做。
我很高兴收到有关所有内容的反馈。如果需要进一步解释,我很乐意这样做。
root.py
import tkinter as tk
from .log_in_window import LogInWind as LIWind
from .sign_up_window import SignUpWind as SuWind
from services.messenger import Messenger
class Root(tk.Tk):
def __init__(self, *args,**kwargs):
super().__init__(*args,**kwargs)
# General variables.
self.frames = {}
self.width_window
self.height_window
self.container = tk.Frame(self,relief="groove")
# General app configurations.
self.title("SECOM")
self.iconbitmap("C:/Users/joshu/Documents/VSC/python/secom/icons/icon.ico")
self.configure(bg="#E0E0E0")
# Container setup.
self.container.pack(side="top", fill="both", expand=True)
self.container.grid_rowconfigure(0, weight=1)
self.container.grid_columnconfigure(0, weight=1)
def createFrame(self, page_name):
"""
INPUT: view object.
OUTPUT: None
Description: creates frame for the view `page_name`.
"""
# Setup `newFrame.`
newFrame = page_name(parent=self.container, controller=self)
newFrame.configure(bg="#E0E0E0")
newFrame.grid(row=0, column=0, sticky=tk.NSEW)
# Add `newFrame` to catalog of frames.
self.__frames[page_name] = newFrame
def showFrame(self, page_name):
"""
INPUT: view object.
OUTPUT: None.
Calls the view `page_name` up front for display.
"""
try:
# Bings requested view to the front.
self.frames[page_name].tkraise()
except KeyError:
# Creates view and displays it.
self.createFrame(page_name)
self.frames[page_name].tkraise()
def setLocation(self):
"""
INPUT: None
OUTPUT: None
Description: Sets window in the middle of the screen.
"""
self.widthWindow = 400
self.heightWindow = 225
widthScreen = self.winfo_screenwidth()
hightScreen = self.winfo_screenheight()
x = (widthScreen / 2) - (self.widthWindow / 2)
y = (hightScreen / 2) - (self.heightWindow / 2)
self.geometry("%dx%d+%d+%d" % (self.widthWindow, self.heightWindow, x, y))
log_in_window.py
import tkinter as tk
import tkinter.font as tkf
from .sign_up_window import SignUpWind as SUWind # <-- circular dependency
class LogInWind(tk.Frame):
def __init__(self, parent, controller):
super().__init__(parent, controller)
# Creation of labels.
self.titleLbl = tk.Label(self,
text="Iniciar Secion",
font=tkf.Font(family="Helvetica", size=15, weight="bold"),
bg="#E0E0E0")
self.userLbl = tk.Label(self,
text="Usuario:",
font=tkf.Font(family="Helvetica", size=10, weight="bold"),
bg="#E0E0E0")
self.pswdLbl = tk.Label(self,
text="Contraseña:",
font=tkf.Font(family="Helvetica", size=10, weight="bold"),
bg="#E0E0E0")
# Creation of entries.
self.userEty = tk.Entry(self)
self.pswdEty = tk.Entry(self, show="*")
# Creation of buttons.
self.logInBtn = tk.Button(self,
width=15,
text="Iniciar Sesion",
font=tkf.Font(family="Helvetica", size=10, weight="bold"),
bg="#0080FF",
################################### ADD COMMAND
fg="#fff")
self.signUpBtn = tk.Button(self,
width=15,
text="Crear cuenta",
font=tkf.Font(family="Helvetica", size=10, weight="bold"),
bg="#0080FF",
command=lambda: controller.showFrame(SUWind), # <---- use object HERE.
fg="#fff")
# Places labels.
self.titleLbl.grid(row=0,
column=0,
padx=400 / 2 - 60,
pady=10,sticky=tk.SW)
self.userLbl.grid(row=1,
column=0,
padx=parent.width_window / 2 - 60,
sticky=tk.SW)
self.pswdLbl.grid(row=3,
column=0,
padx=parent.width_window / 2 - 60,
sticky=tk.W)
# Places entries (string inputs).
self.userEty.grid(row=2,
column=0,
padx=parent.width_window / 2 - 60,
pady=5)
self.pswdEty.grid(row=4,
column=0,
padx=parent.width_window / 2 - 60,
pady=5)
# # Places buttons
self.logInBtn.grid(row=5,column=0, sticky=tk.N)
self.signUpBtn.grid(row=6, column=0, sticky=tk.S, pady=10)
sing_up_window.py
import tkinter as tk
import tkinter.font as tkf
from .log_in_window import LogInWind as LIWind # <-- circular dependency
class SignUpWind(tk.Frame):
def __init__(self, parent, controller):
super().__init__(parent, controller)
# Setup imge for back button.
self.img = tk.PhotoImage(file="C:/Users/joshu/Documents/VSC/python/secom/icons/return.png")
self.img = self.img.subsample(4,4)
# Create label.
self.titleLbl = tk.Label(self,
text="Crear cuenta nueva",
font=tkf.Font(family="Helvetica", size=15, weight="bold"),
bg="#E0E0E0")
self.userLbl = tk.Label(self,
text="Usuario:",
font=tkf.Font(family="Helvetica", size=10, weight="bold"),
bg="#E0E0E0")
self.pswdLbl = tk.Label(self,
text="Contraseña:",
font=tkf.Font(family="Helvetica", size=10, weight="bold"),
bg="#E0E0E0")
self.pswdConfirmLbl = tk.Label(self,
text="Cormirma Contraseña:",
font=tkf.Font(family="Helvetica", size=10, weight="bold"),
bg="#E0E0E0")
# Creation of entries.
self.userEty = tk.Entry(self)
self.pswdEty = tk.Entry(self, show="*")
self.pswdConfirmEty = tk.Entry(self, show="*")
# Creation of button.
self.backBtn = tk.Button(self,
image=self.img,
command=lambda: controller.showFrame(LIWind)) <----- use object HERE.
self.CreateBtn = tk.Button(self,
width=8,
text="Crear",
font=tkf.Font(family="Helvetica", size=10, weight="bold"),
bg="#0080FF",
############################ ADD COMAND
fg="#fff")
# Places labels.
self.titleLbl.grid(row=0, column=0, padx=400 / 2 - 90, sticky=tk.SW)
self.userLbl.grid(row=1, column=0, padx=parent.width_window / 2 - 60, sticky=tk.W)
self.pswdLbl.grid(row=3, column=0, padx=parent.width_window / 2 - 60, sticky=tk.W)
self.pswdConfirmLbl.grid(row=5, column=0, padx=parent.width_window / 2 - 60, sticky=tk.W)
# Places entries (string inputs).
self.userEty.grid(row=2, column=0, padx=parent.width_window / 2 - 60, pady=5, sticky=tk.W)
self.pswdEty.grid(row=4, column=0, padx=parent.width_window / 2 - 60, pady=5, sticky=tk.W)
self.pswdConfirmEty.grid(row=6, column=0, padx=parent.width_window / 2 - 60, pady=5, sticky=tk.W)
# Places buttons
self.backBtn.grid(row=0, column=0,sticky=tk.W)
self.CreateBtn.grid(row=7, column=0, padx=100,sticky=tk.N)
main.py
from views.root import Root
from views.log_in_window import LogInWind as LIWind
if __name__ == '__main__':
root = Root()
root.showFrame(LIWind)
root.mainloop()
【问题讨论】:
-
为什么 sing_up_window.py 从 .root 导入任何东西?它没有使用该文件中的任何内容。如果这是循环依赖的原因,只需将其删除。
-
谢谢我改了。那不应该在那里。我将导入更改为应有的样子。
标签: python-3.x user-interface tkinter object-oriented-analysis