tkinter 框架传播不正常? [英] tkinter frame propagate not behaving?

查看:34
本文介绍了tkinter 框架传播不正常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您取消对 options_frame_title 的注释,您将看到它的行为不正常.我错过了什么吗?该部分刚刚从 preview_frame_title 复制并粘贴,似乎没有问题.

If you uncomment the options_frame_title you will see that it does not behave properly. Am I missing something? That section was just copied and pasted from the preview_frame_title and that seems to have no issues.

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()

推荐答案

我不明白你所说的行为正确"是什么意思.它的行为似乎与设计的一样.

I don't understand what you mean by "behaving properly". It seems to be behaving as it's designed to behave.

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

By default, tkinter frames are designed to shrink (or grow) to fit their child widgets. When you comment out options_frame_title.grid(...), the frame has no visible children so it says the fixed size that you gave it. When you uncomment that line, it causes a label to be placed in the widget which then causes the frame to shrink to fit.

为了让您的问题更加复杂,grid 默认情况下会为具有非零权重的行和列提供任何额外的空间.由于您没有为任何行或列赋予任何权重,因此它们不会获得任何额外空间.

To further complicate the matters for you, grid will by default give any extra space to rows and columns that have a non-zero weight. Since you haven't given any rows or columns any weight, they don't get any extra space.

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

Part of the problem is that you are trying to solve too many problems at once. When first starting out you need to be more methodical. Also, you should consider using pack when you're putting a single widget into another widget. It only takes one line of code to get it to fill its parent rather than three with grid.

专业提示:如果您将小部件创建与小部件布局分开,它真的会有所帮助.您的代码虽然只有几十行,但真的很难阅读.

pro-tip: it really helps if you separate widget creation from widget layout. Your code, even though it's only a couple dozen lines long, is really hard to read.

例如,您应该做的第一件事是从创建最顶层的框架开始,并在将任何小部件放入其中之前让它们正确填充和扩展/收缩.

For example, the first thing you should do is start by creating your top-most frames, and get them to fill and expand/shrink properly before putting any widgets in them.

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

用户不喜欢被剥夺控制权.删除这一行:

User's don't like having control taken away from them. Remove this line:

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

您的用户会感谢您的,在开发过程中,可以更轻松地使用窗口来确保一切都根据需要填充、增长和缩小.

Your users will thank you, and during development it's much easier to play with the window to make sure everything is filling, growing, and shrinking as necessary.

第 1 步:main_frame

由于它似乎旨在包含所有内容,因此使用 pack 是有意义的,因为它是 blank_app 中唯一直接的小部件.

Since it appears this is designed to contain everything, it makes sense to use pack since it is the only widget directly in blank_app.

main_frame = Frame(blank_app, width=750, height=500, bg='gray22')
main_frame.pack(fill="both", expand=True)

仅此而已(加上创建根窗口的前几行,以及对 mainloop 的最终调用),注意窗口大小合适,主框架填充窗户.您可以随意调整窗口大小,主框架将继续填满整个窗口.

With just that (plus the first couple of lines where you create the root window, along with the final call to mainloop), notice how the window is the right size, and the main frame fills the window. You can resize the window all you want and the main frame will continue to fill the whole window.

第 2 步:main_frame 内的小部件

正如我之前提到的,最好将小部件创建和小部件布局分开.此外,在使用 grid 时,一个好的经验法则是始终至少给一行和一列赋予权重.看起来您希望右框架的宽度大约是左框架的 3 倍.这是您可以使用权重的地方.

As I mentioned earlier, it's best to separate widget creation and widget layout. Also, when using grid a good rule of thumb is to always give at least one row and one column a weight. It appears you want the right frame to be about 3x as wide as the left frame. This is where you can use weights.

# 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.

Once again, run the code and notice that as you resize the main window everything still continues to fill the window, and resize properly, and keep the proper proportions. If you don't like the proportions, just change the weights. They can be any number you want. For example, you could use 70 and 240 if you want.

第 3 步:预览帧

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

The preview frame has a label, and I presume you will be putting other stuff under the label. We'll continue to use grid, and just give the row below the label a weight so that it gets all of the extra space. When you add more widgets, you might need to adjust accordingly.

# 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.

This is just like the preview frame: a label at the top, and all of the extra space is given to the empty row number 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")

最后的想法

请注意,您无需担心传播,这是一个有点高级的话题.您也不必担心框架的大小,因为我们使用列权重来提供相对大小,并且您不必为其标签提供大小.

Notice that you don't need to worry about propagation, which is somewhat of an advanced topic. You also don't have to worry about the size of frames since we're using column weights to give relative sizes, and you don't have to give sizes to their labels.

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

We have removed the propagation code, removed the non-resizable behavior, and removed some hard-coded widths, giving us less code but more functionality.

这篇关于tkinter 框架传播不正常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆