tkinter帧传播不正常?

2024-03-28 11:37:59 发布

您现在位置:Python中文网/ 问答频道 /正文

如果取消对options\u frame_title的注释,您将看到它的行为不正常。我错过什么了吗?这个部分只是从预览框标题复制粘贴的,看起来没有问题。在

from tkinter import *


blank_app = Tk()
blank_app.geometry('750x500+250+100')
blank_app.resizable(width=False, height=False)


main_frame = Frame(blank_app, width=750, height=500, bg='gray22')
main_frame.grid(row=0, column=0, sticky=NSEW)

main_title = Label(main_frame, text='App Builder', bg='gray', fg='red', font='Times 12 bold', relief=RIDGE)
main_title.grid(row=0, column=0, padx=2, pady=2, sticky=NSEW, columnspan=2)

preview_frame = Frame(main_frame, width=70, height=465, bg='red', highlightcolor='white', highlightthickness=2)
preview_frame.grid(row=1, column=0, padx=2, pady=2, sticky=NSEW)

preview_frame_title = Label(preview_frame, text='Preview Window', width=70, bg='gray', fg='blue', relief=RIDGE)
preview_frame_title.grid(row=0, column=0, sticky=NSEW)

options_frame = Frame(main_frame, width=240, height=465, bg='blue', highlightcolor='white', highlightthickness=2)
options_frame.grid(row=1, column=1, padx=2, pady=2, sticky=NSEW)

options_frame_title = Label(options_frame, text='Widget Options', width=20, bg='gray', fg='blue', anchor=CENTER, relief=RIDGE)
options_frame_title.grid(row=0, column=0, sticky=NSEW)


blank_app.mainloop()

Tags: apptitlemaincolumnpreviewwidthframegrid
2条回答

我不明白你说的“举止得体”是什么意思。它的行为似乎和设计的一样。在

默认情况下,tkinter框架被设计为缩小(或增长)以适合其子部件。当您注释掉options_frame_title.grid(...)时,该框架没有可见的子级,因此它表示您给它的固定大小。当您取消注释该行时,它会在小部件中放置一个标签,然后使框架收缩以适合。在

为了使问题进一步复杂化,grid将在默认情况下为具有非零权重的行和列提供额外的空间。因为您没有给任何行或列任何权重,所以它们没有任何额外的空间。在

问题的一部分是你试图一次解决太多的问题。刚开始的时候你需要更有条理。另外,当您将一个小部件放入另一个小部件时,应该考虑使用pack。只需一行代码就可以让它填充其父级,而不是用grid填充三行。在


专业提示:如果你把小部件的创建和小部件的布局分开,它会很有帮助。你的代码,即使只有几十行长,也很难阅读。在


例如,首先要做的是创建最顶层的框架,然后在放入任何小部件之前,让它们适当地填充和展开/收缩。在

从头开始

第0步:不要删除调整窗口大小的功能

用户不喜欢失去控制权。删除此行:

blank_app.resizable(width=False, height=False)

你的用户会感谢你的,在开发过程中,你可以更容易地使用这个窗口来确保所有的东西都是满的,增长的,必要时缩小的。在

第1步:主框架

因为它似乎是为了包含所有内容,所以使用pack是有意义的,因为它是blank_app中唯一直接的小部件。在

^{pr2}$

就这样(加上创建根窗口的前几行,以及对mainloop的最后调用),请注意窗口的大小如何正确,主框架填充了窗口。你可以随意调整窗口大小,主框架将继续填充整个窗口。在

<2>主框架内的

正如我前面提到的,最好将小部件创建和小部件布局分开。另外,当使用网格时,一个好的经验法则是总是给至少一行和一列一个权重。看起来你希望右框的宽度是左框的3倍。这是你可以使用重量的地方。在

# widgets in the main frame
main_title = Label(main_frame, text='App Builder', bg='gray', fg='red', font='Times 12 bold', relief=RIDGE)
preview_frame = Frame(main_frame, width=70, height=465, bg='red', highlightcolor='white', highlightthickness=2)
options_frame = Frame(main_frame, width=240, height=465, bg='blue', highlightcolor='white', highlightthickness=2)

# laying out the main frame
main_frame.grid_rowconfigure(1, weight=1)
main_frame.grid_columnconfigure(0, weight=1)
main_frame.grid_columnconfigure(1, weight=3)

main_title.grid(row=0, column=0, padx=2, pady=2, sticky="nsew", columnspan=2)
preview_frame.grid(row=1, column=0, padx=2, pady=2, sticky="nsew")
options_frame.grid(row=1, column=1, padx=2, pady=2, sticky="nsew")

再次运行代码并注意,当您调整主窗口的大小时,所有内容仍将继续填充窗口,并适当调整大小,并保持适当的比例。如果你不喜欢这个比例,就改变一下重量。他们可以是你想要的任何号码。例如,如果需要,可以使用70和240。在

第3步:预览帧

预览框有一个标签,我想你会把其他东西放在标签下。我们将继续使用grid,只需给标签下面的行一个权重,这样它就可以获得所有额外的空间。当您添加更多的小部件时,您可能需要相应地进行调整。在

# widgets in the preview frame
preview_frame_title = Label(preview_frame, text="Preview Window", bg='gray', fg='blue', relief=RIDGE)

# laying out the preview frame
preview_frame.grid_rowconfigure(1, weight=1)
preview_frame.grid_columnconfigure(0, weight=1)
preview_frame_title.grid(row=0, column=0, sticky="nsew")

第4步:选项框

这就像预览帧:在顶部有一个标签,所有多余的空间都被赋予了空行1。在

# widgets in the options frame
options_frame_title = Label(options_frame, text='Widget Options', bg='gray', fg='blue', anchor=CENTER, relief=RIDGE)

# laying out the options frame
options_frame.grid_rowconfigure(1, weight=1)
options_frame.grid_columnconfigure(0, weight=1)
options_frame_title.grid(row=0, column=0, sticky="new")

最后的想法

请注意,您不需要担心传播,这是一个高级主题。您也不必担心帧的大小,因为我们使用列权重来给出相对大小,而且您不必为它们的标签指定大小。在

我们删除了传播代码,删除了不可调整大小的行为,并删除了一些硬编码的宽度,使我们的代码更少,但功能更强是的

好吧,经过一番挖掘,我意识到问题不在于你的options_frame_title,而在于标签所在的框架。在

如果你取消注释options_frame_title并注释掉preview_frame_title,你将看到完全相同的问题。所发生的是框架有一个设定的大小,主窗口符合该框架大小。当你决定把一个标签放进相框里时,这个相框就会符合标签的尺寸。在

你想要做的是用.grid_propagate(0)做一些和你现在做的有点不同的事情。在

我们还需要为正确的帧添加一些权重,以便小部件能够正确填充。在

看看这个代码。在

from tkinter import *

blank_app = Tk()

main_frame = Frame(blank_app,width=700, height=300, bg='gray22')
main_frame.grid(row=0, column=0, sticky=NSEW)

main_frame.grid_propagate(0) #the only place you need to use propagate(0) Thought there are better ways

main_frame.columnconfigure(0, weight = 1) #using weights to manage frames properly helps a lot here
main_frame.columnconfigure(1, weight = 1)
main_frame.rowconfigure(0, weight = 0)
main_frame.rowconfigure(1, weight = 1)

main_title = Label(main_frame, text='App Builder', bg='gray', fg='red', font='Times 12 bold', relief=RIDGE)
main_title.grid(row=0, column=0, columnspan=2, padx=2, pady=2, sticky=NSEW)

preview_frame = Frame(main_frame, bg='red', highlightcolor='white', highlightthickness=2)
preview_frame.grid(row=1, column=0, padx=2, pady=2, sticky=NSEW)
preview_frame.columnconfigure(0, weight = 1)# using weights to manage frames properly helps a lot here

preview_frame_title = Label(preview_frame, text='Preview Window', bg='gray', fg='blue', relief=RIDGE)
preview_frame_title.grid(row=0, column=0, sticky=NSEW)

options_frame = Frame(main_frame, bg='blue', highlightcolor='white', highlightthickness=2)
options_frame.grid(row=1, column=1, padx=2, pady=2, sticky=NSEW)
options_frame.columnconfigure(0, weight = 1) #using weights to manage frames properly helps a lot here

options_frame_title = Label(options_frame, text='Widget Options', bg='gray', fg='blue', anchor=CENTER, relief=RIDGE)
options_frame_title.grid(row=0, column=0, sticky=NSEW)

blank_app.mainloop()

相关问题 更多 >