调整多个网格的大小时遇到​​问题

时间:2011-12-09 16:37:37

标签: python tkinter

我有以下代码。我的问题是我无法正确调整框架的大小。当我运行程序时,一切都如预期的那样。但是当我调整它的大小时,我想保留原始视图。

from Tkinter import *
import os
import sys


ALL=N+S+E+W

class Application(Frame):

    def __init__(self,master=None):
        Frame.__init__(self,master)
        self.master.rowconfigure(0,weight=1)
        self.master.columnconfigure(0,weight=1)
        self.grid(sticky=ALL)

        self.rowconfigure(0,weight=1)
        myframe1=Frame(self,bg='green')
        myframe1.bind("<Button-1>",self.handler1)
        myframe1.grid(row=0,column=0,rowspan=1,columnspan=2,sticky=ALL)
        self.rowconfigure(1,weight=1)
        myframe2=Frame(self,bg='blue')
        myframe2.bind("<Button-1>",self.handler2)
        myframe2.grid(row=1,column=0,rowspan=1,columnspan=2,sticky=ALL)


        buttons=('Red','Blue','Green','Black')
        button=[0]*4
        for c in range(4):
            self.rowconfigure(c+2,weight=1)
            self.columnconfigure(c,weight=1)
            button[c]=Button(self,text="{0}".format(buttons[c]),command=lambda     x=buttons[c]:self.colors(x))
            button[c].grid(row=2,column=c,sticky=E+W)

        self.columnconfigure(4,weight=1)
        self.rowconfigure(6,weight=1)
        button1=Button(self,text='{0}'.format('Open'),command=self.content)
        button1.grid(row=2,column=4,sticky=E+W)


        f=Frame(self,bg='red')
        self.myentry=Entry(f)
        self.myentry.grid(row=0,column=4,sticky=ALL)
        self.text=Text(f)
        self.text.grid(row=1,column=4,sticky=ALL)
        f.grid(row=0,column=2,rowspan=2,columnspan=3,sticky=ALL)

        ...

我尝试了rowconfigurecolumnconfigurerowspancolumnspan的多种组合,但我失败了!

我原来的观点是:

enter image description here

向一个方向调整大小后:

enter image description here

在另一个方向:

enter image description here

白色区域是我想要调整大小的Text小部件(也是蓝色和绿色区域)。

1 个答案:

答案 0 :(得分:9)

您的问题是您似乎不太了解网格的工作原理。例如,您只在红框中放置了两个小部件(self.myentry和self.text),但是您将它们放在第2列和第4列中。您是否知道这些列是相对于其父级的,而不是GUI作为整个?您希望它们位于红框<0>的第0列中,然后您需要它的父级的第二列中的红框。

解决这个问题的方法是分而治之。首先,将主屏幕划分为逻辑部分,并布置这些逻辑部分,以便正确调整大小。然后,对于每个部件内的任何东西,泡沫,冲洗重复。使用框架进行组织是可行的方法。

以下是我将如何解决您的问题(尽管解决此问题的方法肯定不止一种)。首先,屏幕有两个主要区域:顶部有绿色,蓝色和红色框架及其内容,底部有按住按钮。顶部区域应在所有方向上生长和收缩,底部区域仅在X方向上生长。我会为此创建两个框架,每个部件一个,并使用pack,因为pack是最简单的几何管理器。顶部框架应配置为填充两个方向并展开。底部(带按钮)应仅填充X方向。

现在,您有两个相互独立的区域,并具有适当的调整大小行为:“主”区域和“工具栏”区域。你可以自由地安排这些框架的内部内容,而不必担心它会如何影响主要布局。

在底部框架中,如果您希望所有窗口小部件的大小相同,请使用pack并让它们全部填充X并展开,它们将同样填充该区域。如果您希望它们的大小不同,请使用网格,以便您可以单独控制每个列。

对于顶部,它有三个子部分:红色,绿色和蓝色框架。由于它们不是全部水平或垂直排列,我会使用网格。在单元格0,0中放置绿色,在单元格0,1中放置蓝色,在跨越两行的单元格1,1中放置红色。给第0行和第1列赋予1的权重,这样就可以消除所有的松弛。

正如我之前所写,这不是“分而治之”这个具体问题的唯一方法。而不是将主应用程序视为两个部分 - 顶部和底部,顶部有三个子部分,另一个选择是看到您的主窗口有四个部分:绿色,蓝色,红色和工具栏。关键不是选择完美的定义,而是将布局问题分解为从外部工作的块。

这是一个有效的例子:

from Tkinter  import *

ALL=N+S+E+W

class Application(Frame):

    def __init__(self,master=None):
        Frame.__init__(self,master)

        # the UI is made up of two major areas: a bottom row
        # of buttons, and a top area that fills the result of 
        # UI
        top_frame = Frame(self)
        button_frame = Frame(self)

        button_frame.pack(side="bottom", fill="x")
        top_frame.pack(side="top", fill="both", expand=True)

        # top frame is made up of three sections: two smaller
        # regions on the left, and a larger region on the right
        ul_frame = Frame(top_frame, background="green", width=200)
        ll_frame = Frame(top_frame, background="blue", width=200)
        right_frame = Frame(top_frame, background="red")

        ul_frame.grid(row=0, column=0, sticky=ALL)
        ll_frame.grid(row=1, column=0, sticky=ALL)
        right_frame.grid(row=0, column=1, rowspan=2, sticky=ALL)
        top_frame.columnconfigure(1, weight=1)
        top_frame.rowconfigure(0, weight=1)
        top_frame.rowconfigure(1, weight=1)

        # the right frame is made up of two widgets, an entry
        # on top and a text below
        entry = Entry(right_frame)
        text = Text(right_frame)

        entry.pack(side="top", fill="x")
        text.pack(side="top", fill="both", expand=True)

        # the button frame has five equally spaced buttons
        for color in ('Red', 'Blue', 'Green', 'Black'):
            b = Button(button_frame, text=color)
            b.pack(side="left", fill="x", expand=True)
        quit_button = Button(button_frame, text="Quit")
        quit_button.pack(side="left", fill="x", expand=True)

root = Tk()
app = Application(root)
app.pack(fill="both", expand=True)
root.mainloop()