简体   繁体   English

grid_propagate 和 columnspan 之间的奇怪交互

[英]Odd interaction between grid_propagate and columnspan

Assigning a columnspan (other than 1) to a child object appears to negate the effects of uniform=1 and grid_propagate(False).将列跨度(1 除外)分配给子 object 似乎否定了 uniform=1 和 grid_propagate(False) 的影响。 Here is a simple example of what I mean (click the text to toggle back and forth and observe the change).这是我的意思的一个简单示例(单击文本来回切换并观察变化)。

import tkinter as tk

class TestInterface:
    def __init__(self, master):
        self.master = master
        self.master.title("Interface Template")
        self.master.configure(bg='#000000', relief=tk.RIDGE, borderwidth=16)
        self.master.attributes('-fullscreen', True)

        self.demonstration_frame = tk.Frame()
        self.dummy_frame = tk.Frame()
        self.button = tk.Button()

        self.button1()

    def button1(self):
        self.remake_test_frame()
        self.button = tk.Button(self.demonstration_frame, text="LONG PHRASE MODIFYING THE GRID STRUCTURE", bg='#111111',
                                relief=tk.FLAT, fg="#FFFFFF", font=('Courier', 12), anchor='center', borderwidth=6,
                                command=lambda: self.button2())
        self.button.grid(row=2, column=3, columnspan=2, sticky='nsew')

    def button2(self):
        self.remake_test_frame()
        self.button = tk.Button(self.demonstration_frame, text="LONG PHRASE BEING CUT OFF AS INTENDED", bg='#111111',
                                relief=tk.FLAT, fg="#FFFFFF", font=('Courier', 12), anchor='center', borderwidth=6,
                                command=lambda: self.button1())
        self.button.grid(row=2, column=3, sticky='nsew')

    def remake_test_frame(self):
        self.demonstration_frame.destroy()
        self.demonstration_frame = tk.Frame(master=self.master, relief=tk.FLAT, borderwidth=4, bg='blue')
        self.demonstration_frame.pack(expand=True, fill="both")
        self.demonstration_frame.grid_propagate(False)
        for k in range(4):
            self.demonstration_frame.grid_rowconfigure(k, weight=1, uniform=1)
        for i in range(6):
            self.demonstration_frame.grid_columnconfigure(i, weight=1, uniform=1)
            for j in range(4):
                self.dummy_frame = tk.Frame(self.demonstration_frame, relief=tk.RIDGE, borderwidth=1,
                                            bg='#' + str(int(j / 2)) + str(int(j / 2)) + str(int(j / 2))
                                               + str(int(i / 2)) + str(int(i / 2)) + str(int(i / 2)))
                self.dummy_frame.grid(row=j, column=i, sticky='nsew')

root = tk.Tk()
my_gui = TestInterface(root)
root.mainloop()

I have demonstration_frame being re-formed from scratch with each button click, so we know that frame is being created in the same way each time.每次单击按钮时,我都会从头开始重新形成 demo_frame,因此我们知道每次都以相同的方式创建框架。 The dummy_frames are just to make clear what is happening. dummy_frames 只是为了弄清楚发生了什么。 The only difference between self.button1() and self.button2() is the removal of "columnspan=2." self.button1() 和 self.button2() 之间的唯一区别是删除了“columnspan=2”。

I want these grid lines locked in place (I'm fine with text being invisible/off-frame).我希望这些网格线锁定在适当的位置(我可以接受不可见/离框的文本)。 Can anyone explain why columnspan is changing the behavior of grid_propagate() here?谁能解释一下为什么 columnspan 在这里改变了 grid_propagate() 的行为?

edit: here is the code without the demonstration_frame.destroy method.编辑:这是没有 demo_frame.destroy 方法的代码。 It behaves the exact same way.它的行为方式完全相同。

import tkinter as tk


class TestInterface:
    def __init__(self, master):
        self.master = master
        self.master.title("Interface Template")
        self.master.configure(bg='#000000', relief=tk.RIDGE, borderwidth=16)
        self.master.attributes('-fullscreen', True)

        self.demonstration_frame = tk.Frame(master=self.master, relief=tk.FLAT, borderwidth=4, bg='blue')
        self.demonstration_frame.pack(expand=True, fill="both")
        self.demonstration_frame.grid_propagate(False)
        for k in range(4):
            self.demonstration_frame.grid_rowconfigure(k, weight=1, uniform=1)
        for i in range(6):
            self.demonstration_frame.grid_columnconfigure(i, weight=1, uniform=1)
            for j in range(4):
                self.dummy_frame = tk.Frame(self.demonstration_frame, relief=tk.RIDGE, borderwidth=1,
                                            bg='#' + str(int(j / 2)) + str(int(j / 2)) + str(int(j / 2))
                                               + str(int(i / 2)) + str(int(i / 2)) + str(int(i / 2)))
                self.dummy_frame.grid(row=j, column=i, sticky='nsew')
        self.dummy_frame = tk.Frame()
        self.button = tk.Button()

        self.button1()

    def button1(self):
        self.button = tk.Button(self.demonstration_frame, text="LONG PHRASE MODIFYING THE GRID STRUCTURE", bg='#111111',
                                relief=tk.FLAT, fg="#FFFFFF", font=('Courier', 12), anchor='center', borderwidth=6,
                                command=lambda: self.button2())
        self.button.grid(row=2, column=3, columnspan=2, sticky='nsew')

    def button2(self):
        self.button.destroy()
        self.button = tk.Button(self.demonstration_frame, text="LONG PHRASE BEING CUT OFF AS INTENDED", bg='#111111',
                                relief=tk.FLAT, fg="#FFFFFF", font=('Courier', 12), anchor='center', borderwidth=6,
                                command=lambda: self.button1())
        self.button.grid(row=2, column=3, sticky='nsew')


root = tk.Tk()
my_gui = TestInterface(root)
root.mainloop()

Can anyone explain why columnspan is changing the behavior of grid_propagate() here?谁能解释一下为什么 columnspan 在这里改变了 grid_propagate() 的行为?

In this example, columnspan is not changing the behavior of grid_propagate .在这个例子中, columnspan没有改变grid_propagate的行为。 Turning off grid propagation only tells the parent not to grow or shrink based on the children.关闭网格传播只会告诉父级不要根据子级进行增长或缩小。 The size of the parent isn't changing when you use columnspan - the frame stays the size that it was.当您使用columnspan时,父级的大小不会改变 - 框架保持原来的大小。 What changes is the size of the inner columns, which has nothing to do with geometry propagation.变化的是内列的大小,这与几何传播无关。

I've never seen this behavior before, and it does seem unintuitive.我以前从未见过这种行为,而且看起来确实不直观。 However, I think it's working as designed.但是,我认为它按设计工作。

The canonical documentation for the grid algorithm starts with the following:网格算法的规范文档从以下内容开始:

"To compute the minimum size of a layout, the grid geometry manager first looks at all content whose columnspan and rowspan values are one, and computes the nominal size of each row or column to be either the minsize for that row or column, or the sum of the padding plus the size of the largest content, whichever is greater. After that the rows or columns in each uniform group adapt to each other. " “为了计算布局的最小尺寸,网格几何管理器首先查看其列跨度和行跨度值为 1 的所有内容,并计算每行或列的标称尺寸为该行或列的最小尺寸,或者填充的总和加上最大内容的大小,以较大者为准。之后每个统一组中的行或列相互适应。

At this point in the algorithm the rows and columns in your example should all be the same width and height.在算法的这一点上,您示例中的行和列都应该具有相同的宽度和高度。 So far, so good.到目前为止,一切都很好。

The documentation then addresses what happens when widgets span two or more rows or columns:然后,该文档解决了小部件跨越两行或多列时会发生的情况:

"Then the content whose row-spans or column-spans are greater than one are examined. If a group of rows or columns need to be increased in size in order to accommodate these content, then extra space is added to each row or column in the group according to its weight. For each group whose weights are all zero, the additional space is apportioned equally." “然后检查行跨度或列跨度大于一个的内容。如果需要增加一组行或列的大小以容纳这些内容,则在每个行或列中添加额外的空间组根据其权重。对于权重都为零的每个组,额外的空间被平均分配。

This seems to describe exactly what you are seeing: extra space is added to columns 3 and 4 so that the button will fit.这似乎准确地描述了您所看到的:在第 3 列和第 4 列中添加了额外的空间,以便按钮适合。

My guess is that you can put the button in a frame that has no width and height, and turn geometry propagation off in that frame.我的猜测是,您可以将按钮放在没有宽度和高度的框架中,并在该框架中关闭几何传播。 Make sure you use options that cause the button to fill the frame.确保使用使按钮填充框架的选项。 You can then put that frame where you are currently putting the button, spanning two columns.然后,您可以将该框架放在当前放置按钮的位置,跨越两列。 Since the frame will have a requested size of 1x1 it will not cause the columns to grow.由于框架的请求大小为 1x1,因此不会导致列增长。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM