我对tkinter相当陌生,我使用的是这篇帖子顶部评论中的代码:Switch between two frames in tkinter,并进行了一些更改,以便能够在两个框架之间切换。问题是当我为此添加第二个框架或其他不是第一个框架时,我无法将其居中。如果我说我仍然很了解tkinter和python,而我并没有真正理解这篇文章中的代码是如何工作的,我对此表示歉意。这是我的代码:
import tkinter as tk
class MainView(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
self.frames["LoginFrame"] = LoginFrame(parent=container, controller=self)
self.frames["RegisterFrame"] = RegisterFrame(parent=container, controller=self)
self.frames["LoginFrame"].grid(row=0, column=0, sticky="NESW")
self.frames["RegisterFrame"].grid(row=0, column=0, sticky="NESW")
self.ShowFrame("LoginFrame")
def ShowFrame(self, PageName):
frame = self.frames[PageName]
frame.tkraise()
class LoginFrame(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
WelcomeLabel = tk.Label(self, text="Welcome to Detention Organiser!",font=(None,20) ).grid(columnspan=2)
UsernameLabel = tk.Label(self, text="Username",font=(None,15) ).grid(row=1, sticky="E")
PasswordLabel = tk.Label(self, text="Password",font=(None,15) ).grid(row=2, sticky="E")
UsernameEntry = tk.Entry(self).grid(row=1, column=1, sticky="W")
PasswordEntry = tk.Entry(self, show="*").grid(row=2, column=1, sticky="W")
LoginButton = tk.Button(self, text="Login").grid(columnspan=2)
RegisterButton = tk.Button(self, text="Sign Up",command=lambda: controller.ShowFrame("RegisterFrame")).grid(columnspan=2)
class RegisterFrame(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.Variable = tk.StringVar()
self.Variable.set("7A")
RegisterLabel = tk.Label(self, text="Register",font=(None,20)).grid(columnspan=2)
UsernameLabel = tk.Label(self, text="Username",font=(None,15)).grid(row=1, sticky="E")
PasswordLabel = tk.Label(self, text="Password",font=(None,15)).grid(row=2, sticky="E")
FormGroupLabel = tk.Label(self, text="Form Group",font=(None,15) ).grid(row=3, sticky="E")
UsernameEntry = tk.Entry(self).grid(row=1, column=1, sticky="W")
PasswordEntry = tk.Entry(self, show="*").grid(row=2, column=1, sticky="W")
FormGroupDrop = tk.OptionMenu(self,self.Variable,"7A","7B","8A","8B").grid(row=3, column=1, sticky="W")
RegisterButton = tk.Button(self, text="Register",command=lambda: controller.ShowFrame("RegisterFrame"))
RegisterButton.grid(columnspan=2)
BackButton = tk.Button(self, text="Back",command=lambda: controller.ShowFrame("LoginFrame")).grid(columnspan=2)
if __name__ == "__main__":
app = MainView()
app.geometry("640x360")
app.mainloop()
答案 0 :(得分:0)
第一件事,通常是在程序中,避免做类似的事情:
UsernameEntry = tk.Entry(self).grid(row=1, column=1, sticky="W")
因为变量UsernameEntry
并非您所期望的tk.Entry
,因此有时肯定会导致错误。而是使用以下之一:
# If you need the variable later
UsernameEntry = tk.Entry(self)
UsernameEntry.grid(row=1, column=1, sticky="W")
# Otherwise
tk.Entry(self).grid(row=1, column=1, sticky="W")
现在,回到您的问题。缺少的是您不知道程序应如何分配剩余空间(不需要空间来包含窗口小部件)。默认情况下,网格会将您的小部件放置在尽可能靠近容器顶部/左侧的位置。要更改此行为,您将需要使用grid_columnconfigure
和/或grid_rowconfigure
。例如,
self.grid_columnconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=1)
告诉程序剩余空间应在列0和列1之间平均分配。权重可以是任何非负整数值:
self.grid_columnconfigure(0, weight=3)
self.grid_columnconfigure(1, weight=0)
self.grid_columnconfigure(2, weight=1)
这告诉程序将剩余空间的3/4分配给第0列,将None分配给第1列,将1/4分配给第2列。默认情况下,所有权重均为0。
然后,您的课程LoginFrame
和RegisterFrame
可能看起来像
class LoginFrame(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.grid_rowconfigure(5, weight=1) # Fills vertical space below the last row
self.grid_columnconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=1)
tk.Label(self, text="Welcome to Detention Organiser!",font=(None,20) ).grid(columnspan=2)
tk.Label(self, text="Username",font=(None,15)).grid(row=1, sticky="E")
tk.Label(self, text="Password",font=(None,15)).grid(row=2, sticky="E")
tk.Entry(self).grid(row=1, column=1, sticky="W")
tk.Entry(self, show="*").grid(row=2, column=1, sticky="W")
tk.Button(self, text="Login").grid(row=3, columnspan=2)
tk.Button(self, text="Sign Up",command=lambda: controller.ShowFrame("RegisterFrame")).grid(row=4, columnspan=2)
class RegisterFrame(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.Variable = tk.StringVar()
self.Variable.set("7A")
self.grid_rowconfigure(5, weight=1) # Fills vertical space below the last row
self.grid_columnconfigure(0, weight=0)
self.grid_columnconfigure(1, weight=1)
tk.Label(self, text="Register",font=(None,20)).grid(columnspan=2)
tk.Label(self, text="Username",font=(None,15)).grid(row=1, sticky="E")
tk.Label(self, text="Password",font=(None,15)).grid(row=2, sticky="E")
tk.Label(self, text="Form Group",font=(None,15) ).grid(row=3, sticky="E")
tk.Entry(self).grid(row=1, column=1, sticky="W")
tk.Entry(self, show="*").grid(row=2, column=1, sticky="W")
tk.OptionMenu(self,self.Variable,"7A","7B","8A","8B").grid(row=3, column=1, sticky="W")
RegisterButton = tk.Button(self, text="Register",command=lambda: controller.ShowFrame("RegisterFrame"))
RegisterButton.grid(columnspan=2)
tk.Button(self, text="Back",command=lambda: controller.ShowFrame("LoginFrame")).grid(columnspan=2)
最后,tkinter有许多不同的选项,您需要进行测试才能真正了解它们的工作原理。在进行一些测试时,建议您广泛使用选项bg="COLOR"
,该选项将更改窗口小部件的背景并准确告诉您其边界。例如,
tk.Frame.__init__(self, parent, bg="RED")