tkinter:使用具有多个框架和功能的单个按钮

时间:2017-03-05 17:16:51

标签: python loops for-loop tkinter

我有一个名为' pages'它由多个帧x1到x5组成。我希望能够使用tkraise()在它们之间导航。 x1帧只会在中心有一个下一个按钮来提升x2,x5只会在中心有一个前一个按钮来提升x4。帧x2到x4将具有下一个和前一个按钮,相应地提升下一帧和前一帧,并且必须调整按钮的位置以使它们彼此相邻。

使用只有一个上一个和下一个按钮的for循环是否可以实现所有这些功能?我能够使用我的for循环在帧x2到x4中获得前一个/下一个按钮,但是我不确定该命令应该放置什么以便它们可以提高相应的上一帧/下一帧(我把它放在lambda旁边)。愿有人请帮忙。

from tkinter import *

root = Tk()

box = Frame(root)
box.pack(fill=BOTH, expand=True)
box.grid_columnconfigure(0, weight=1)
box.grid_rowconfigure(0, weight=1)

x1 = Frame(box, bg="gainsboro")
x1.grid(row=0, sticky="nsew")

x2 = Frame(box, bg="red")
x2.grid(row=0, sticky="nsew")

x3 = Frame(box, bg="blue")
x3.grid(row=0, sticky="nsew")

x4 = Frame(box, bg="green")
x4.grid(row=0, sticky="nsew")

x5 = Frame(box, bg="snow")
x5.grid(row=0, sticky="nsew")

frames = [x1, x2, x3, x4, x5]

next_button = Button(frames[0], text="Next", command=lambda: frames[1].tkraise())
next_button.pack()

previous_button = Button(frames[-1], text="Previous", command=lambda: frames[-2].tkraise())
previous_button.pack()

for x in frames[1:4]:
    next_button_2 = Button(x, text="Next", command=lambda: ?)
    next_button_2.pack(side=RIGHT)

    previous_button_2 = Button(x, text="Previous", command=lambda: ?)
    previous_button_2.pack(side=LEFT)

x1.tkraise()

root.mainloop()

1 个答案:

答案 0 :(得分:0)

迭代frames[1:4]在这里不会很好用,因为它让你没有简单的方法来获得下一个/上一个帧。尝试迭代索引:

for i in range(1,4):
    nb = Button(frames[i], text="Next", command=frames[i+1].tkraise)
    nb.pack(side=RIGHT)
    pb = Button(frames[i], text="Previous", command=frames[i-1].tkraise)
    pb.pack(side=LEFT)

注意:我只是将tkraise方法本身设置为命令而不是lambdas。这是可能的,因为它不需要参数。否则,你会在循环中遇到Lambda的常见问题:它们访问的任何局部变量总是会看到它们在循环的最后一次迭代期间所具有的值。如果您想使用lambdas,则必须将i的值作为参数捕获:lambda i=i: frames[i+1].tkraise()例如。

实际上,在同一个循环中处理结束情况相当简单,从而节省了一些代码重复:

for i in range(len(frames)):
    if i != len(frames) - 1:
        nb = Button(frames[i], text="Next", command=frames[i+1].tkraise)
        nb.pack(side=RIGHT)
    if i != 0:
        pb = Button(frames[i], text="Previous", command=frames[i-1].tkraise)
        pb.pack(side=LEFT)