tkinter - 使用按钮在帧之间来回切换
tkinter - Going Back and Forth Between Frames Using Buttons
我需要功能,最好是一个功能,当按下下一步和后退按钮时可以在页面之间来回移动。我想这可以通过将布尔变量分配给后退和下一个按钮(不确定是否可以这样做)来确定您是要前进还是后退所有页面的有序列表来完成。需要知道当前提出的框架的索引。索引可用于找出下一页,然后将其提升。如果当前索引为 0 或最后一个索引(在本例中为 2),然后分别按返回或下一步,那么您将转到主页 class 框架,在本例中为 BlankPage.
import tkinter as tk
from tkinter import ttk
class Program(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.iconbitmap(self, default = "")
tk.Tk.wm_title(self, "")
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (Add, BlankPage):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row = 0, column = 0, sticky = "nsew")
self.show_frame(Add)
def show_frame(self,cont):
frame = self.frames[cont]
frame.tkraise()
class Add(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
innerFrame = tk.Frame(self)
innerFrame.place(relx=.5, rely=.5, anchor="c", relwidth=1.0, relheight=1.0)
innerFrame.grid_rowconfigure(1, weight=1)
innerFrame.grid_columnconfigure(0, weight=1)
name = tk.Label(innerFrame, text = "User")
name.grid(row=0, sticky="NE")
pagename = tk.Label(innerFrame, text = "Label")
pagename.grid(row=0, sticky="N")
next = ttk.Button(innerFrame, text = "Next", command = self.changePage)
next.grid(row=2, sticky="E")
back = ttk.Button(innerFrame, text = "Back", command = self.changePage)
back.grid(row=2, sticky="W")
###########################################################################################################
self.pageThree = tk.Frame(innerFrame)
self.pageThree.grid(row=1)
self.pageThree.grid_rowconfigure(0, weight=1)
self.pageThree.grid_columnconfigure(0, weight=1)
pagename = tk.Label(self.pageThree, text = "Page 3")
pagename.grid(row=0, sticky="N")
###########################################################################################################
self.pageTwo = tk.Frame(innerFrame)
self.pageTwo.grid(row=1)
self.pageTwo.grid_rowconfigure(0, weight=1)
self.pageTwo.grid_columnconfigure(0, weight=1)
pagename = tk.Label(self.pageTwo, text = "Page 2")
pagename.grid(row=0, sticky="N")
###########################################################################################################
self.pageOne = tk.Frame(innerFrame)
self.pageOne.grid(row=1)
self.pageOne.grid_rowconfigure(0, weight=1)
self.pageOne.grid_columnconfigure(0, weight=1)
pagename = tk.Label(self.pageOne, text = "Page 1")
pagename.grid(row=0, sticky="N")
###########################################################################################################
def changePage(self,buttonBool):
pages = [self.pageOne,self.pageTwo,self.pageThree]
#find current raised page and set to variable 'current'
position = pages.index(current)
if (postion==0 and buttonBool==False) or (postion==len(pages)-1 and buttonBool==True):
show_frame(BlankPage)
elif buttonBool==True:
pages[position+1].tkraise()
else:
pages[position-1].tkraise()
class BlankPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
app = Program()
app.state('zoomed')
app.mainloop()
changePage 功能是我的尝试,请问如何完成?
你已经非常接近让这一切正常工作了,在我自己看了一些之后我找不到任何(不是太复杂的)方法来找出最重要的 Frame
所以这可能是最好的只记录当前位置:
def __init__(self, parent, controller):
...
self.position = 0 #the index of the pages list
并且要将 buttonBool
传递给 changePage
,您可以 something from here(Tlapička 在我看来提供了最佳解决方案,因为 lambda
表达式使代码行太长了)
def __init__(self, parent, controller):
...
# button commands don't have an event but sometimes you use these callbacks for both .bind and buttons
# so having event=None makes it work for both.
def go_next(event=None):
self.changePage(True)
next = ttk.Button(innerFrame, text = "Next", command = go_next)
next.grid(row=2, sticky="E")
def go_back(event=None):
self.changePage(False)
back = ttk.Button(innerFrame, text = "Back", command = go_back)
back.grid(row=2, sticky="W")
...
有了这两个(并将self.position
实现到changePage
)你可以完成你最初的要求,下面的一切都是我所说的code reviewer。
虽然使用布尔值会起作用,但这种处理回调额外参数的策略允许您将 any 参数传递给 changePage
,因此它可能会简化条件changePage
如果页面发生变化(所以 1 或 -1):
def go_next(event=None):
self.changePage(1)
next = ttk.Button(innerFrame, text = "Next", command = go_next)
next.grid(row=2, sticky="E")
def go_back(event=None):
self.changePage(-1)
back = ttk.Button(innerFrame, text = "Back", command = go_back)
back.grid(row=2, sticky="W")
#this is for the last suggestion
self.nextButton = next
self.backButton = back
...
然后 changePage
可能看起来像这样,虽然我不确定如果您更改到无效页面 self.position
会发生什么:
def changePage(self,change):
pages = [self.pageOne,self.pageTwo,self.pageThree]
new_position = self.position + change
if (new_postion < 0) or (new_postion <= len(pages)):
show_frame(BlankPage)
#not sure how you would handle the new position here
else:
pages[new_position].tkraise()
self.position = new_position
更好的是,如果您保留对 next
和 back
按钮的引用,您可以 config
它们表明它是 end/beginning:
def changePage(self,change):
pages = [self.pageOne,self.pageTwo,self.pageThree]
new_position = self.position + change
if (0 <= new_postion < len(pages)):
pages[new_position].tkraise()
self.position = new_position
else:
show_frame(BlankPage)
if new_position+1 >= len(pages):
self.nextButton.config(text="End") #, state=tk.DISABLED)
else:
self.nextButton.config(text="Next") #, state=tk.NORMAL)
if new_position-1 < 0:
self.backButton.config(text="First") #, state=tk.DISABLED)
else:
self.backButton.config(text="Back") #, state=tk.NORMAL)
这样即使内容中没有指示,您也会知道何时到达终点。 (或者您可以禁用按钮以防止过去)
我需要功能,最好是一个功能,当按下下一步和后退按钮时可以在页面之间来回移动。我想这可以通过将布尔变量分配给后退和下一个按钮(不确定是否可以这样做)来确定您是要前进还是后退所有页面的有序列表来完成。需要知道当前提出的框架的索引。索引可用于找出下一页,然后将其提升。如果当前索引为 0 或最后一个索引(在本例中为 2),然后分别按返回或下一步,那么您将转到主页 class 框架,在本例中为 BlankPage.
import tkinter as tk
from tkinter import ttk
class Program(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.iconbitmap(self, default = "")
tk.Tk.wm_title(self, "")
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (Add, BlankPage):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row = 0, column = 0, sticky = "nsew")
self.show_frame(Add)
def show_frame(self,cont):
frame = self.frames[cont]
frame.tkraise()
class Add(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
innerFrame = tk.Frame(self)
innerFrame.place(relx=.5, rely=.5, anchor="c", relwidth=1.0, relheight=1.0)
innerFrame.grid_rowconfigure(1, weight=1)
innerFrame.grid_columnconfigure(0, weight=1)
name = tk.Label(innerFrame, text = "User")
name.grid(row=0, sticky="NE")
pagename = tk.Label(innerFrame, text = "Label")
pagename.grid(row=0, sticky="N")
next = ttk.Button(innerFrame, text = "Next", command = self.changePage)
next.grid(row=2, sticky="E")
back = ttk.Button(innerFrame, text = "Back", command = self.changePage)
back.grid(row=2, sticky="W")
###########################################################################################################
self.pageThree = tk.Frame(innerFrame)
self.pageThree.grid(row=1)
self.pageThree.grid_rowconfigure(0, weight=1)
self.pageThree.grid_columnconfigure(0, weight=1)
pagename = tk.Label(self.pageThree, text = "Page 3")
pagename.grid(row=0, sticky="N")
###########################################################################################################
self.pageTwo = tk.Frame(innerFrame)
self.pageTwo.grid(row=1)
self.pageTwo.grid_rowconfigure(0, weight=1)
self.pageTwo.grid_columnconfigure(0, weight=1)
pagename = tk.Label(self.pageTwo, text = "Page 2")
pagename.grid(row=0, sticky="N")
###########################################################################################################
self.pageOne = tk.Frame(innerFrame)
self.pageOne.grid(row=1)
self.pageOne.grid_rowconfigure(0, weight=1)
self.pageOne.grid_columnconfigure(0, weight=1)
pagename = tk.Label(self.pageOne, text = "Page 1")
pagename.grid(row=0, sticky="N")
###########################################################################################################
def changePage(self,buttonBool):
pages = [self.pageOne,self.pageTwo,self.pageThree]
#find current raised page and set to variable 'current'
position = pages.index(current)
if (postion==0 and buttonBool==False) or (postion==len(pages)-1 and buttonBool==True):
show_frame(BlankPage)
elif buttonBool==True:
pages[position+1].tkraise()
else:
pages[position-1].tkraise()
class BlankPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
app = Program()
app.state('zoomed')
app.mainloop()
changePage 功能是我的尝试,请问如何完成?
你已经非常接近让这一切正常工作了,在我自己看了一些之后我找不到任何(不是太复杂的)方法来找出最重要的 Frame
所以这可能是最好的只记录当前位置:
def __init__(self, parent, controller):
...
self.position = 0 #the index of the pages list
并且要将 buttonBool
传递给 changePage
,您可以 something from here(Tlapička 在我看来提供了最佳解决方案,因为 lambda
表达式使代码行太长了)
def __init__(self, parent, controller):
...
# button commands don't have an event but sometimes you use these callbacks for both .bind and buttons
# so having event=None makes it work for both.
def go_next(event=None):
self.changePage(True)
next = ttk.Button(innerFrame, text = "Next", command = go_next)
next.grid(row=2, sticky="E")
def go_back(event=None):
self.changePage(False)
back = ttk.Button(innerFrame, text = "Back", command = go_back)
back.grid(row=2, sticky="W")
...
有了这两个(并将self.position
实现到changePage
)你可以完成你最初的要求,下面的一切都是我所说的code reviewer。
虽然使用布尔值会起作用,但这种处理回调额外参数的策略允许您将 any 参数传递给 changePage
,因此它可能会简化条件changePage
如果页面发生变化(所以 1 或 -1):
def go_next(event=None):
self.changePage(1)
next = ttk.Button(innerFrame, text = "Next", command = go_next)
next.grid(row=2, sticky="E")
def go_back(event=None):
self.changePage(-1)
back = ttk.Button(innerFrame, text = "Back", command = go_back)
back.grid(row=2, sticky="W")
#this is for the last suggestion
self.nextButton = next
self.backButton = back
...
然后 changePage
可能看起来像这样,虽然我不确定如果您更改到无效页面 self.position
会发生什么:
def changePage(self,change):
pages = [self.pageOne,self.pageTwo,self.pageThree]
new_position = self.position + change
if (new_postion < 0) or (new_postion <= len(pages)):
show_frame(BlankPage)
#not sure how you would handle the new position here
else:
pages[new_position].tkraise()
self.position = new_position
更好的是,如果您保留对 next
和 back
按钮的引用,您可以 config
它们表明它是 end/beginning:
def changePage(self,change):
pages = [self.pageOne,self.pageTwo,self.pageThree]
new_position = self.position + change
if (0 <= new_postion < len(pages)):
pages[new_position].tkraise()
self.position = new_position
else:
show_frame(BlankPage)
if new_position+1 >= len(pages):
self.nextButton.config(text="End") #, state=tk.DISABLED)
else:
self.nextButton.config(text="Next") #, state=tk.NORMAL)
if new_position-1 < 0:
self.backButton.config(text="First") #, state=tk.DISABLED)
else:
self.backButton.config(text="Back") #, state=tk.NORMAL)
这样即使内容中没有指示,您也会知道何时到达终点。 (或者您可以禁用按钮以防止过去)