如何在 Tkinter 中使用 grid() 制作一个简单的向导?
How to make a simple wizard using grid() in Tkinter?
见谅。我是 Tkinter 的新手,对 python 的理解只有 simple/modest。我的总体目标是制作一个类似向导的程序,其中用户在程序进行时输入不断增加的细节(根据某些输入出现某些帧)。我只是想让核心向导的想法发挥作用,并且 运行 遇到了一些问题。这是我的代码(我已经注释掉了其他来源暗示在正确轨道上但对我来说失败的事情):
from Tkinter import *
root = Tk()
#root.minsize(300,300) ?
#root.geometry("300x300") ?
def next():
move(+1)
def prev():
move(-1)
def exit_program():
root.destroy()
page1 = Frame(root, width=300, height=300)
page1.grid()
#page1.grid(row=0,column=0, sticky="nsew") ?
#page1.grid_rowconfigure(0, weight=1) ?
#page1.grid_columnconfigure(0, weight=1) ?
p1_label = Label(page1, text='This is page 1 of the wizard.').grid(column=1, row=0)
p1_quit = Button(page1, text="Quit", command=exit_program).grid(column=1, row=2)
p1_next = Button(page1, text="Next", command=next).grid(column=2, row=2)
page2 = Frame(root)
p2_label = Label(page2, text='This is page 2 of the wizard.').grid(column=1, row=0)
p2_prev = Button(page2, text="Prev", command=prev).grid(column=1, row=2)
p2_next = Button(page2, text="Next", command=next).grid(column=2, row=2)
page3 = Frame(root)
p3_label = Label(page3, text='This is page 3 of the wizard.').grid(column=1, row=0)
p3_prev = Button(page3, text="Prev", command=prev).grid(column=1, row=2)
p3_quit = Button(page3, text="Quit", command=exit_program).grid(column=2, row=2)
pages = [page1, page2, page3]
current = page1
def move(dirn):
global current
idx = pages.index(current) + dirn
if not 0 <= idx < len(pages):
return
current.grid_forget()
current = pages[idx]
current.grid()
root.mainloop()
我有几个问题:
- 为什么第一个(和所有)框架缩小到内部小部件的大小,即使我已将宽度和高度设置为一定数量?我在网上看过,显然 grid_propagate(False) 关闭了重新调整大小,但强烈不推荐这样做,而且直接失败(是的,它使 window 成为我想要的尺寸,但是 "grid"本身还在左上)。我不应该能够说明框架的尺寸,并且网格与这些尺寸对齐(即保留网格组织,而不是区域)?这个问题与向导过程有关吗?我不太愿意,但我可能仍然可以在一个 window.
中编写程序
- 为什么网格显示为 2x2?不应该是 3x3 因为第零个条目有效吗?我在位置 (2x2) 中放置了一个按钮 (p1_next)。是不是因为 0 列中没有任何内容,grid() 将其删除并将所有内容向左移动?
- 这是我要实现的目标的最佳方法吗?恐怕我只知道 OOP 的绝对基础知识,如果可能的话我宁愿避免(这个程序虽然对我来说很大,但按照现代软件开发标准最终会变得微不足道)。
根据我的学习经验,我隐约觉得这个问题不是一蹴而就的,我需要进行重大的范式转换才能理解这一点。无论哪种方式,任何帮助将不胜感激
如果这是重复的,我很抱歉。谢谢!
Why does the first (and all) frame(s) shrink to the size of widgets
inside, even though I have set the width and height to be a certain
amount? ... Shouldn't I be able to state the dimensions of a frame,
and the grid aligns itself with those dimensions
这就是 tkinter 设计的工作原理:容器会收缩以适合其内容。 99% 的时间这是正确的解决方案。正如您所观察到的,您可以关闭几何传播,但这有副作用,并且需要您完成通常由 tkinter 更好地处理的工作。如果您真的坚持将帧设置为特定大小,通常可以关闭传播。
如果您的具体情况,强制主要 window 为特定大小比强制框架为特定大小更有意义。然后框架将增长(或缩小)以适应主要 window。您可以使用根 window.
的 geometry
方法来执行此操作
Why does the grid appear to be 2x2? Shouldn't it be 3x3 because the
zeroth entry is valid? I have placed a button (p1_next) in position
(2x2). Is it because nothing is in the 0 column, grid() removes it and
shifts everything to the left?
如果列中没有任何内容,则该列的默认宽度将为零(除非它是统一组的一部分,或者具有最小尺寸等)。行也是如此——默认情况下,空行的高度为零。
Is this the best approach for what I'm trying to accomplish?
这很难回答。可能没有 "best" 方法。
您可能想查看 this answer 的相关问题,其中展示了一种通过堆叠帧然后将当前帧提升到堆栈顶部来在一组帧之间切换的方法。
见谅。我是 Tkinter 的新手,对 python 的理解只有 simple/modest。我的总体目标是制作一个类似向导的程序,其中用户在程序进行时输入不断增加的细节(根据某些输入出现某些帧)。我只是想让核心向导的想法发挥作用,并且 运行 遇到了一些问题。这是我的代码(我已经注释掉了其他来源暗示在正确轨道上但对我来说失败的事情):
from Tkinter import *
root = Tk()
#root.minsize(300,300) ?
#root.geometry("300x300") ?
def next():
move(+1)
def prev():
move(-1)
def exit_program():
root.destroy()
page1 = Frame(root, width=300, height=300)
page1.grid()
#page1.grid(row=0,column=0, sticky="nsew") ?
#page1.grid_rowconfigure(0, weight=1) ?
#page1.grid_columnconfigure(0, weight=1) ?
p1_label = Label(page1, text='This is page 1 of the wizard.').grid(column=1, row=0)
p1_quit = Button(page1, text="Quit", command=exit_program).grid(column=1, row=2)
p1_next = Button(page1, text="Next", command=next).grid(column=2, row=2)
page2 = Frame(root)
p2_label = Label(page2, text='This is page 2 of the wizard.').grid(column=1, row=0)
p2_prev = Button(page2, text="Prev", command=prev).grid(column=1, row=2)
p2_next = Button(page2, text="Next", command=next).grid(column=2, row=2)
page3 = Frame(root)
p3_label = Label(page3, text='This is page 3 of the wizard.').grid(column=1, row=0)
p3_prev = Button(page3, text="Prev", command=prev).grid(column=1, row=2)
p3_quit = Button(page3, text="Quit", command=exit_program).grid(column=2, row=2)
pages = [page1, page2, page3]
current = page1
def move(dirn):
global current
idx = pages.index(current) + dirn
if not 0 <= idx < len(pages):
return
current.grid_forget()
current = pages[idx]
current.grid()
root.mainloop()
我有几个问题:
- 为什么第一个(和所有)框架缩小到内部小部件的大小,即使我已将宽度和高度设置为一定数量?我在网上看过,显然 grid_propagate(False) 关闭了重新调整大小,但强烈不推荐这样做,而且直接失败(是的,它使 window 成为我想要的尺寸,但是 "grid"本身还在左上)。我不应该能够说明框架的尺寸,并且网格与这些尺寸对齐(即保留网格组织,而不是区域)?这个问题与向导过程有关吗?我不太愿意,但我可能仍然可以在一个 window. 中编写程序
- 为什么网格显示为 2x2?不应该是 3x3 因为第零个条目有效吗?我在位置 (2x2) 中放置了一个按钮 (p1_next)。是不是因为 0 列中没有任何内容,grid() 将其删除并将所有内容向左移动?
- 这是我要实现的目标的最佳方法吗?恐怕我只知道 OOP 的绝对基础知识,如果可能的话我宁愿避免(这个程序虽然对我来说很大,但按照现代软件开发标准最终会变得微不足道)。
根据我的学习经验,我隐约觉得这个问题不是一蹴而就的,我需要进行重大的范式转换才能理解这一点。无论哪种方式,任何帮助将不胜感激
如果这是重复的,我很抱歉。谢谢!
Why does the first (and all) frame(s) shrink to the size of widgets inside, even though I have set the width and height to be a certain amount? ... Shouldn't I be able to state the dimensions of a frame, and the grid aligns itself with those dimensions
这就是 tkinter 设计的工作原理:容器会收缩以适合其内容。 99% 的时间这是正确的解决方案。正如您所观察到的,您可以关闭几何传播,但这有副作用,并且需要您完成通常由 tkinter 更好地处理的工作。如果您真的坚持将帧设置为特定大小,通常可以关闭传播。
如果您的具体情况,强制主要 window 为特定大小比强制框架为特定大小更有意义。然后框架将增长(或缩小)以适应主要 window。您可以使用根 window.
的geometry
方法来执行此操作
Why does the grid appear to be 2x2? Shouldn't it be 3x3 because the zeroth entry is valid? I have placed a button (p1_next) in position (2x2). Is it because nothing is in the 0 column, grid() removes it and shifts everything to the left?
如果列中没有任何内容,则该列的默认宽度将为零(除非它是统一组的一部分,或者具有最小尺寸等)。行也是如此——默认情况下,空行的高度为零。
Is this the best approach for what I'm trying to accomplish?
这很难回答。可能没有 "best" 方法。
您可能想查看 this answer 的相关问题,其中展示了一种通过堆叠帧然后将当前帧提升到堆栈顶部来在一组帧之间切换的方法。