使用 tkinter 和 grid 以绝对方式定位按钮
Using tkinter and grid to position buttons in an absolute manner
我刚开始使用 tkinter,我正在努力让我的按钮呈现在屏幕的最底部,均匀分布,填满整个底行。
我一直在使用 grid() 来尝试这样做,但没有成功。我希望这三个按钮在不影响页面其他组件(例如顶部的文本)的情况下呈现。我正在尝试完成一个具有三个按钮的 window,每个按钮呈现一个您可以与之交互的不同页面。
下面是我的完整代码,我非常感谢您提供的任何见解。
from cgitb import text
import tkinter as tk
from tkinter import ttk
LARGEFONT =("Verdana", 35)
class tkinterApp(tk.Tk):
# __init__ function for class tkinterApp
def __init__(self, *args, **kwargs):
# __init__ function for class Tk
tk.Tk.__init__(self, *args, **kwargs)
# creating a container
container = tk.Frame(self)
container.grid(row=0, column=0)
container.grid_rowconfigure(0)
container.grid_columnconfigure(0)
# initializing frames to an empty array
self.frames = {}
# iterating through a tuple consisting
# of the different page layouts
for F in (StartPage, Page1, Page2):
frame = F(container, self)
# initializing frame of that object from
# startpage, page1, page2 respectively with
# for loop
self.frames[F] = frame
frame.grid(row = 0, column = 0, sticky ="nsew")
self.show_frame(StartPage)
# to display the current frame passed as
# parameter
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
# label of frame Layout 2
welcome = ttk.Label(self, text ="Welcome!", font = LARGEFONT)
welcome.grid(row = 0, column = 2, )
button1 = ttk.Button(self, text ="Page 1", command = lambda : controller.show_frame(Page1))
button1.grid(row = 9, column = 1, padx = 10, pady = 10)
button2 = ttk.Button(self, text ="Page 2", command = lambda : controller.show_frame(Page2))
button2.grid(row = 9, column = 2, padx = 10, pady = 10)
# second window frame page1
class Page1(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self, text ="Page 1", font = LARGEFONT)
label.grid(row = 0, column = 2, )
button1 = ttk.Button(self, text ="StartPage", command = lambda : controller.show_frame(StartPage))
button1.grid(row = 9, column = 1, padx = 10, pady = 10)
button2 = ttk.Button(self, text ="Page 2", command = lambda : controller.show_frame(Page2))
button2.grid(row = 9, column = 2, padx = 10, pady = 10)
# third window frame page2
class Page2(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self, text ="Page 3", font = LARGEFONT)
label.grid(row = 0, column = 2, )
button1 = ttk.Button(self, text ="Page 1", command = lambda : controller.show_frame(Page1))
button1.grid(row = 9, column = 1, padx = 10, pady = 10)
button2 = ttk.Button(self, text ="Startpage", command = lambda : controller.show_frame(StartPage))
button2.grid(row = 9, column = 2, padx = 10, pady = 10)
# Driver Code
app = tkinterApp()
app.geometry("800x425")
app.mainloop()
您正在使用 grid 和 pack。你永远不应该混合这两个布局管理器,因为它会导致未知的错误行为。也许您的代码在剔除该 pack 调用后会起作用。
我对您的代码进行了以下更改以使其正常工作:
网格化根 window 以便 container
将占据 window 中的整个 space。
#Gridding the tkinter window
self.grid_rowconfigure(0, weight = 1)
self.grid_columnconfigure(0, weight = 1)
container
使用 sticky = 'nsew'
向各个方向扩展。
container.grid(row=0, column=0, sticky = 'nsew')
已修改 __init__
并将 tkraise
添加到所有 页面 类.
我将使用下面的代码块进行解释。
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
# label of frame Layout 2
welcome = ttk.Label(self, text ="Welcome!", font = LARGEFONT)
welcome.grid(row = 0, column = 2)
#Creating a frame exclusively for the buttons
self.frame_buttons = tk.Frame(parent)
self.frame_buttons.grid(row = 1, column = 0, columnspan = 3)
self.frame_buttons.grid_remove()
#Gridding self.frame_buttons
self.frame_buttons.grid_columnconfigure((0,1), weight = 1)
self.frame_buttons.grid_rowconfigure(0, weight = 1)
button1 = ttk.Button(self.frame_buttons, text ="Page 1", command = lambda : controller.show_frame(Page1))
button1.grid(row = 0, column = 0, padx = 10, pady = 10)
button2 = ttk.Button(self.frame_buttons, text ="Page 2", command = lambda : controller.show_frame(Page2))
button2.grid(row = 0, column = 1, padx = 10, pady = 10)
def tkraise(self):
self.frame_buttons.grid()
self.frame_buttons.tkraise()
tk.Frame.tkraise(self)
在__init__
方法中,创建self.frame_buttons
并将所有按钮添加到其中。它使用 .grid
显示,然后立即使用 .grid_remove()
删除。使用.grid_remove()
的好处是grid选项被记住了,以后可以直接用.grid()
来显示frame。
在tkraise
方法中,显示框架,提升到顶部,然后tk.Frame.tkraise(self)
用于调用in-built方法。
工作代码:
from cgitb import text
import tkinter as tk
from tkinter import ttk
LARGEFONT =("Verdana", 35)
class tkinterApp(tk.Tk):
# __init__ function for class tkinterApp
def __init__(self, *args, **kwargs):
# __init__ function for class Tk
tk.Tk.__init__(self, *args, **kwargs)
#Gridding the tkinter window
self.grid_rowconfigure(0, weight = 1)
self.grid_columnconfigure(0, weight = 1)
# creating a container
container = tk.Frame(self)
container.grid(row=0, column=0, sticky = 'nsew')
container.grid_rowconfigure(0, weight = 1)
container.grid_columnconfigure(0, weight = 1)
# initializing frames to an empty array
self.frames = {}
# iterating through a tuple consisting
# of the different page layouts
for F in (StartPage, Page1, Page2):
frame = F(container, self)
# initializing frame of that object from
# startpage, page1, page2 respectively with
# for loop
self.frames[F] = frame
frame.grid(row = 0, column = 0, sticky ="nsew")
self.show_frame(StartPage)
# to display the current frame passed as
# parameter
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
# label of frame Layout 2
welcome = ttk.Label(self, text ="Welcome!", font = LARGEFONT)
welcome.grid(row = 0, column = 2)
#Creating a frame exclusively for the buttons
self.frame_buttons = tk.Frame(parent)
self.frame_buttons.grid(row = 1, column = 0, columnspan = 3)
self.frame_buttons.grid_remove()
#Gridding self.frame_buttons
self.frame_buttons.grid_columnconfigure((0,1), weight = 1)
self.frame_buttons.grid_rowconfigure(0, weight = 1)
button1 = ttk.Button(self.frame_buttons, text ="Page 1", command = lambda : controller.show_frame(Page1))
button1.grid(row = 0, column = 0, padx = 10, pady = 10)
button2 = ttk.Button(self.frame_buttons, text ="Page 2", command = lambda : controller.show_frame(Page2))
button2.grid(row = 0, column = 1, padx = 10, pady = 10)
def tkraise(self):
self.frame_buttons.grid()
self.frame_buttons.tkraise()
tk.Frame.tkraise(self)
# second window frame page1
class Page1(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self, text ="Page 1", font = LARGEFONT)
label.grid(row = 0, column = 2)
#Creating a frame exclusively for the buttons
self.frame_buttons = tk.Frame(parent)
self.frame_buttons.grid(row = 1, column = 0, columnspan = 3)
self.frame_buttons.grid_remove()
#Gridding self.frame_buttons
self.frame_buttons.grid_columnconfigure((0,1), weight = 1)
self.frame_buttons.grid_rowconfigure(0, weight = 1)
button1 = ttk.Button(self.frame_buttons, text ="StartPage", command = lambda : controller.show_frame(StartPage))
button1.grid(row = 0, column = 0, padx = 10, pady = 10)
button2 = ttk.Button(self.frame_buttons, text ="Page 2", command = lambda : controller.show_frame(Page2))
button2.grid(row = 0, column = 1, padx = 10, pady = 10)
def tkraise(self):
self.frame_buttons.grid()
self.frame_buttons.tkraise()
tk.Frame.tkraise(self)
# third window frame page2
class Page2(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self, text ="Page 2", font = LARGEFONT)
label.grid(row = 0, column = 2)
#Creating a frame exclusively for the buttons
self.frame_buttons = tk.Frame(parent)
self.frame_buttons.grid(row = 1, column = 0, columnspan = 3)
self.frame_buttons.grid_remove()
#Gridding self.frame_buttons
self.frame_buttons.grid_columnconfigure((0,1), weight = 1)
self.frame_buttons.grid_rowconfigure(0, weight = 1)
button1 = ttk.Button(self.frame_buttons, text ="Page 1", command = lambda : controller.show_frame(Page1))
button1.grid(row = 0, column = 0, padx = 10, pady = 10)
button2 = ttk.Button(self.frame_buttons, text ="Startpage", command = lambda : controller.show_frame(StartPage))
button2.grid(row = 0, column = 1, padx = 10, pady = 10)
def tkraise(self):
self.frame_buttons.grid()
self.frame_buttons.tkraise()
tk.Frame.tkraise(self)
# Driver Code
app = tkinterApp()
app.geometry("800x425")
app.mainloop()
我刚开始使用 tkinter,我正在努力让我的按钮呈现在屏幕的最底部,均匀分布,填满整个底行。
我一直在使用 grid() 来尝试这样做,但没有成功。我希望这三个按钮在不影响页面其他组件(例如顶部的文本)的情况下呈现。我正在尝试完成一个具有三个按钮的 window,每个按钮呈现一个您可以与之交互的不同页面。
下面是我的完整代码,我非常感谢您提供的任何见解。
from cgitb import text
import tkinter as tk
from tkinter import ttk
LARGEFONT =("Verdana", 35)
class tkinterApp(tk.Tk):
# __init__ function for class tkinterApp
def __init__(self, *args, **kwargs):
# __init__ function for class Tk
tk.Tk.__init__(self, *args, **kwargs)
# creating a container
container = tk.Frame(self)
container.grid(row=0, column=0)
container.grid_rowconfigure(0)
container.grid_columnconfigure(0)
# initializing frames to an empty array
self.frames = {}
# iterating through a tuple consisting
# of the different page layouts
for F in (StartPage, Page1, Page2):
frame = F(container, self)
# initializing frame of that object from
# startpage, page1, page2 respectively with
# for loop
self.frames[F] = frame
frame.grid(row = 0, column = 0, sticky ="nsew")
self.show_frame(StartPage)
# to display the current frame passed as
# parameter
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
# label of frame Layout 2
welcome = ttk.Label(self, text ="Welcome!", font = LARGEFONT)
welcome.grid(row = 0, column = 2, )
button1 = ttk.Button(self, text ="Page 1", command = lambda : controller.show_frame(Page1))
button1.grid(row = 9, column = 1, padx = 10, pady = 10)
button2 = ttk.Button(self, text ="Page 2", command = lambda : controller.show_frame(Page2))
button2.grid(row = 9, column = 2, padx = 10, pady = 10)
# second window frame page1
class Page1(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self, text ="Page 1", font = LARGEFONT)
label.grid(row = 0, column = 2, )
button1 = ttk.Button(self, text ="StartPage", command = lambda : controller.show_frame(StartPage))
button1.grid(row = 9, column = 1, padx = 10, pady = 10)
button2 = ttk.Button(self, text ="Page 2", command = lambda : controller.show_frame(Page2))
button2.grid(row = 9, column = 2, padx = 10, pady = 10)
# third window frame page2
class Page2(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self, text ="Page 3", font = LARGEFONT)
label.grid(row = 0, column = 2, )
button1 = ttk.Button(self, text ="Page 1", command = lambda : controller.show_frame(Page1))
button1.grid(row = 9, column = 1, padx = 10, pady = 10)
button2 = ttk.Button(self, text ="Startpage", command = lambda : controller.show_frame(StartPage))
button2.grid(row = 9, column = 2, padx = 10, pady = 10)
# Driver Code
app = tkinterApp()
app.geometry("800x425")
app.mainloop()
您正在使用 grid 和 pack。你永远不应该混合这两个布局管理器,因为它会导致未知的错误行为。也许您的代码在剔除该 pack 调用后会起作用。
我对您的代码进行了以下更改以使其正常工作:
网格化根 window 以便 container
将占据 window 中的整个 space。
#Gridding the tkinter window
self.grid_rowconfigure(0, weight = 1)
self.grid_columnconfigure(0, weight = 1)
container
使用 sticky = 'nsew'
向各个方向扩展。
container.grid(row=0, column=0, sticky = 'nsew')
已修改 __init__
并将 tkraise
添加到所有 页面 类.
我将使用下面的代码块进行解释。
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
# label of frame Layout 2
welcome = ttk.Label(self, text ="Welcome!", font = LARGEFONT)
welcome.grid(row = 0, column = 2)
#Creating a frame exclusively for the buttons
self.frame_buttons = tk.Frame(parent)
self.frame_buttons.grid(row = 1, column = 0, columnspan = 3)
self.frame_buttons.grid_remove()
#Gridding self.frame_buttons
self.frame_buttons.grid_columnconfigure((0,1), weight = 1)
self.frame_buttons.grid_rowconfigure(0, weight = 1)
button1 = ttk.Button(self.frame_buttons, text ="Page 1", command = lambda : controller.show_frame(Page1))
button1.grid(row = 0, column = 0, padx = 10, pady = 10)
button2 = ttk.Button(self.frame_buttons, text ="Page 2", command = lambda : controller.show_frame(Page2))
button2.grid(row = 0, column = 1, padx = 10, pady = 10)
def tkraise(self):
self.frame_buttons.grid()
self.frame_buttons.tkraise()
tk.Frame.tkraise(self)
在__init__
方法中,创建self.frame_buttons
并将所有按钮添加到其中。它使用 .grid
显示,然后立即使用 .grid_remove()
删除。使用.grid_remove()
的好处是grid选项被记住了,以后可以直接用.grid()
来显示frame。
在tkraise
方法中,显示框架,提升到顶部,然后tk.Frame.tkraise(self)
用于调用in-built方法。
工作代码:
from cgitb import text
import tkinter as tk
from tkinter import ttk
LARGEFONT =("Verdana", 35)
class tkinterApp(tk.Tk):
# __init__ function for class tkinterApp
def __init__(self, *args, **kwargs):
# __init__ function for class Tk
tk.Tk.__init__(self, *args, **kwargs)
#Gridding the tkinter window
self.grid_rowconfigure(0, weight = 1)
self.grid_columnconfigure(0, weight = 1)
# creating a container
container = tk.Frame(self)
container.grid(row=0, column=0, sticky = 'nsew')
container.grid_rowconfigure(0, weight = 1)
container.grid_columnconfigure(0, weight = 1)
# initializing frames to an empty array
self.frames = {}
# iterating through a tuple consisting
# of the different page layouts
for F in (StartPage, Page1, Page2):
frame = F(container, self)
# initializing frame of that object from
# startpage, page1, page2 respectively with
# for loop
self.frames[F] = frame
frame.grid(row = 0, column = 0, sticky ="nsew")
self.show_frame(StartPage)
# to display the current frame passed as
# parameter
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
# label of frame Layout 2
welcome = ttk.Label(self, text ="Welcome!", font = LARGEFONT)
welcome.grid(row = 0, column = 2)
#Creating a frame exclusively for the buttons
self.frame_buttons = tk.Frame(parent)
self.frame_buttons.grid(row = 1, column = 0, columnspan = 3)
self.frame_buttons.grid_remove()
#Gridding self.frame_buttons
self.frame_buttons.grid_columnconfigure((0,1), weight = 1)
self.frame_buttons.grid_rowconfigure(0, weight = 1)
button1 = ttk.Button(self.frame_buttons, text ="Page 1", command = lambda : controller.show_frame(Page1))
button1.grid(row = 0, column = 0, padx = 10, pady = 10)
button2 = ttk.Button(self.frame_buttons, text ="Page 2", command = lambda : controller.show_frame(Page2))
button2.grid(row = 0, column = 1, padx = 10, pady = 10)
def tkraise(self):
self.frame_buttons.grid()
self.frame_buttons.tkraise()
tk.Frame.tkraise(self)
# second window frame page1
class Page1(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self, text ="Page 1", font = LARGEFONT)
label.grid(row = 0, column = 2)
#Creating a frame exclusively for the buttons
self.frame_buttons = tk.Frame(parent)
self.frame_buttons.grid(row = 1, column = 0, columnspan = 3)
self.frame_buttons.grid_remove()
#Gridding self.frame_buttons
self.frame_buttons.grid_columnconfigure((0,1), weight = 1)
self.frame_buttons.grid_rowconfigure(0, weight = 1)
button1 = ttk.Button(self.frame_buttons, text ="StartPage", command = lambda : controller.show_frame(StartPage))
button1.grid(row = 0, column = 0, padx = 10, pady = 10)
button2 = ttk.Button(self.frame_buttons, text ="Page 2", command = lambda : controller.show_frame(Page2))
button2.grid(row = 0, column = 1, padx = 10, pady = 10)
def tkraise(self):
self.frame_buttons.grid()
self.frame_buttons.tkraise()
tk.Frame.tkraise(self)
# third window frame page2
class Page2(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self, text ="Page 2", font = LARGEFONT)
label.grid(row = 0, column = 2)
#Creating a frame exclusively for the buttons
self.frame_buttons = tk.Frame(parent)
self.frame_buttons.grid(row = 1, column = 0, columnspan = 3)
self.frame_buttons.grid_remove()
#Gridding self.frame_buttons
self.frame_buttons.grid_columnconfigure((0,1), weight = 1)
self.frame_buttons.grid_rowconfigure(0, weight = 1)
button1 = ttk.Button(self.frame_buttons, text ="Page 1", command = lambda : controller.show_frame(Page1))
button1.grid(row = 0, column = 0, padx = 10, pady = 10)
button2 = ttk.Button(self.frame_buttons, text ="Startpage", command = lambda : controller.show_frame(StartPage))
button2.grid(row = 0, column = 1, padx = 10, pady = 10)
def tkraise(self):
self.frame_buttons.grid()
self.frame_buttons.tkraise()
tk.Frame.tkraise(self)
# Driver Code
app = tkinterApp()
app.geometry("800x425")
app.mainloop()