Tkinter Python应用程序中的布局管理问题

时间:2014-02-22 11:09:19

标签: python user-interface layout tkinter

我正在使用一个小的Tkinter程序,我在Python中作为我自己的CMS的前端,关于窗口控件的布局。我是Tkinter的新手,但不是Python,但我正在努力使用网格布局管理器按我想要的方式安排我的控件。 这是我所瞄准的(可怕的)模型: enter image description here

但是我的代码(下面)只呈现这个: enter image description here

这是我的代码:

'''
Configure main window controls
'''
postTtlFrame = Frame(tkRoot, bg="red")
postTtlLbl = Label(postTtlFrame, text="Page title:").grid(row=0, column=0)
postTtlEnt = Entry(postTtlFrame).grid(row=0, column=1)
postTtlFrame.grid(row=0, column=0)

postTxtFrame = Frame(tkRoot, bg="blue")
postTxtLbl = Label(postTxtFrame, text="Page body content:").grid(row=0, column=0)
postTxtArea = Text(postTxtFrame).grid(row=1, columnspan=1)
postTxtFrame.grid(row=1, column=0)

pageConfigFrame = Frame(tkRoot, bg="green")
headerDirecLbl = Label(tkRoot, text="Page header location:").grid(row=0, column=0)
headerDirecEnt = Entry(tkRoot).grid(row=0, column=1)
footerDirecLbl = Label(tkRoot, text="Page footer location:").grid(row=1, column=0)
footerDirecEnt = Entry(tkRoot).grid(row=1, column=1)
stylesDirecLbl = Label(tkRoot, text="Page stylesheet location:").grid(row=2, column=0)
stylesDirecEnt = Entry(tkRoot).grid(row=2, column=1)
outputDirecLbl = Label(tkRoot, text="Page output location:").grid(row=3, column=0)
outputDirecEnt = Entry(tkRoot).grid(row=3, column=1)
pageConfigFrame.grid(row=2, column=0)

buttonsFrame = Frame(tkRoot, bg="orange")
postBtn = Button(tkRoot, text="Post").grid(row=0, column=0)
exitBtn = Button(tkRoot, text="Exit", command=quitTk).grid(row=0, column=1)
buttonsFrame.grid(row=3, column=0)

请有人向我解释一下到底出了什么问题!

提前致谢, Ilmiont

3 个答案:

答案 0 :(得分:1)

首先,如果您同时调用grid(或packplace),则将小部件分配给变量毫无意义。 foo=Label(..).grid(...)将始终返回None,因为grid(...)始终返回None。此外,当您将布局与窗口小部件创建分开时,我发现布局问题很多更容易解决。

所以,让我们开始吧:

'''
Configure main window controls
'''
postTtlFrame = Frame(tkRoot, bg="red")
postTxtFrame = Frame(tkRoot, bg="blue")
pageConfigFrame = Frame(tkRoot, bg="green")
buttonsFrame = Frame(tkRoot, bg="orange")

postTtlFrame.grid(row=0, column=0)
postTxtFrame.grid(row=1, column=0)
pageConfigFrame.grid(row=2, column=0)
buttonsFrame.grid(row=3, column=0)

postTtlLbl = Label(postTtlFrame, text="Page title:")
postTtlEnt = Entry(postTtlFrame).grid(row=0, column=1)
postTtlLbl.grid(row=0, column=0)

postTxtLbl = Label(postTxtFrame, text="Page body content:")
postTxtArea = Text(postTxtFrame)
postTxtLbl.grid(row=0, column=0)
postTxtArea.grid(row=1, columnspan=1)

headerDirecLbl = Label(tkRoot, text="Page header location:")
headerDirecEnt = Entry(tkRoot)
footerDirecLbl = Label(tkRoot, text="Page footer location:")
footerDirecEnt = Entry(tkRoot)
stylesDirecLbl = Label(tkRoot, text="Page stylesheet location:")
stylesDirecEnt = Entry(tkRoot)
outputDirecLbl = Label(tkRoot, text="Page output location:")
outputDirecEnt = Entry(tkRoot)
postBtn = Button(tkRoot, text="Post")
exitBtn = Button(tkRoot, text="Exit")

headerDirecLbl.grid(row=0, column=0)
headerDirecEnt.grid(row=0, column=1)
footerDirecLbl.grid(row=1, column=0)
footerDirecEnt.grid(row=1, column=1)
stylesDirecLbl.grid(row=2, column=0)
stylesDirecEnt.grid(row=2, column=1)
outputDirecLbl.grid(row=3, column=0)
outputDirecEnt.grid(row=3, column=1)
postBtn.grid(row=0, column=0)
exitBtn.grid(row=0, column=1)

现在,我认为你可以更清楚地看到发生了什么。我看到的问题是:

  1. 您似乎想要将事情分为四个主要区域,但您的模型显示前三个区域中的所有内容都应该共享相同的网格结构,因此我不确定您为什么要创建这些框架
  2. 您没有为行或列分配任何权重,因此他们不会增长和缩小您的期望
  3. 大多数小部件都共享tkRoot的共同父级,而不是您创建的组织框架,因此框架最终没有用处
  4. 由于许多小部件共享同一个父级,因此您最终会在同一个网格单元格中将多个小部件放在一起。
  5. 您没有使用sticky属性,因此小部件无法填充其列。
  6. 所有这一切的解决方案取决于您正在尝试实现的效果。如果您需要四个独立区域,则需要确保每个窗口小部件都有适合其父窗口的框架,而不是将大多数窗口小部件集中在tkRoot框架中。这使得例如postTtlEnt可能不会与其他条目小部件对齐。

    如果您想要四个独立区域并且希望postTtlEnt小部件与其他所有内容对齐,请摆脱中间框架并放置所有内容成一个网格。

    可能你想要混合 - 按钮不一定需要共享相同的网格,但所有的条目小部件应该共享同一个网格。这是我将如何做到的。请注意,我只有一个额外的内部框架,用于按钮。其他所有人都有共同的父母。另请注意,我为一行和一列赋予权重,以便您获得正确的调整大小行为:

    这是一个完整的,有效的例子。它并不能完全匹配您的模型:退出和发布按钮没有自己的专用列,但如果您真的想要,可以根据需要进行操作。按钮上方的空间似乎浪费了,所以我选择将按钮直接放在输入小部件下面。

    '''
    Configure main window controls
    '''
    
    postTtlLbl = Label(tkRoot, text="Page title:")
    postTxtLbl = Label(tkRoot, text="Page body content:")
    headerDirecLbl = Label(tkRoot, text="Page header location:")
    footerDirecLbl = Label(tkRoot, text="Page footer location:")
    stylesDirecLbl = Label(tkRoot, text="Page stylesheet location:")
    outputDirecLbl = Label(tkRoot, text="Page output location:")
    
    postTtlEnt = Entry(tkRoot)
    postTxtArea = Text(tkRoot)
    footerDirecEnt = Entry(tkRoot)
    headerDirecEnt = Entry(tkRoot)
    stylesDirecEnt = Entry(tkRoot)
    outputDirecEnt = Entry(tkRoot)
    
    buttonsFrame = Frame(tkRoot, bg="orange")
    postBtn = Button(buttonsFrame, text="Post")
    exitBtn = Button(buttonsFrame, text="Exit")
    postBtn.pack(side="right")
    exitBtn.pack(side="right")
    
    postTtlLbl.grid(row=0, column=0, sticky="w")
    postTxtLbl.grid(row=1, column=0, sticky="w")
    headerDirecLbl.grid(row=3, column=0, sticky="w")
    footerDirecLbl.grid(row=4, column=0, sticky="w")
    stylesDirecLbl.grid(row=5, column=0, sticky="w")
    outputDirecLbl.grid(row=6, column=0, sticky="w")
    
    postTtlEnt.grid(row=0, column=1, sticky="ew")
    postTxtArea.grid(row=2, column=0, columnspan=2, sticky="nsew")
    headerDirecEnt.grid(row=3, column=1, sticky="ew")
    footerDirecEnt.grid(row=4, column=1, sticky="ew")
    stylesDirecEnt.grid(row=5, column=1, sticky="ew")
    outputDirecEnt.grid(row=6, column=1, sticky="ew")
    buttonsFrame.grid(row=7, column=0, sticky="ew", columnspan=2)
    
    tkRoot.grid_rowconfigure(2, weight=1)
    tkRoot.grid_columnconfigure(1, weight=1)
    

答案 1 :(得分:1)

是的,我现在正在工作@jeanrjc,我的代码完全是我现在意识到的错误;这是我最后使用的内容:

'''
Configure main window controls
'''
postTtlFrame = Frame(tkRoot)
postTtlLbl = Label(postTtlFrame, text="Page title:").grid(row=0, column=0)
postTtlEnt = Entry(postTtlFrame).grid(row=0, column=1)
postTtlFrame.grid(row=0, column=0, sticky=W)

postTxtFrame = Frame(tkRoot)
postTxtLbl = Label(postTxtFrame, text="Page body content:").grid(row=0, column=0, sticky=W)
postTxtArea = Text(postTxtFrame).grid(row=1, columnspan=1)
postTxtFrame.grid(row=1, column=0, sticky=W)

pageConfigFrame = Frame(tkRoot)
headerDirecLbl = Label(pageConfigFrame, text="Page header location:").grid(row=0, column=0, sticky=W)
headerDirecEnt = Entry(pageConfigFrame).grid(row=0, column=1)
footerDirecLbl = Label(pageConfigFrame, text="Page footer location:").grid(row=1, column=0, sticky=W)
footerDirecEnt = Entry(pageConfigFrame).grid(row=1, column=1)
stylesDirecLbl = Label(pageConfigFrame, text="Page stylesheet location:").grid(row=2, column=0, sticky=W)
stylesDirecEnt = Entry(pageConfigFrame).grid(row=2, column=1)
outputDirecLbl = Label(pageConfigFrame, text="Page output location:").grid(row=3, column=0, sticky=W)
outputDirecEnt = Entry(pageConfigFrame).grid(row=3, column=1)
pageConfigFrame.grid(row=2, column=0, sticky=W)

buttonsFrame = Frame(tkRoot)
postBtn = Button(buttonsFrame, text="Post").grid(row=0, column=0)
exitBtn = Button(buttonsFrame, text="Exit", command=quitTk).grid(row=0, column=1)
buttonsFrame.grid(row=3, column=0, sticky=E)

现在我有以下结果,这就是我想要的: enter image description here

尽管如此,谢谢!

答案 2 :(得分:0)

我设法得到了一些非常接近你想要的东西:

from Tkinter import *

root = Tk()
content = Label(root, padx=30,pady=30,background = "white")
content.grid(column=0, row=0, sticky=(N, S, E, W))
title_frame = Label(content, borderwidth=5, relief="sunken", padx=30,pady=30,background = "white")
title_frame.grid(column=0, row=0, sticky=(N))
body_frame = Label(content, borderwidth=5, relief="sunken", padx=30,pady=30,background = "white")
body_frame.grid(column=0, row=1, sticky=(N,W,E))
config_frame = Label(content, borderwidth=5, relief="sunken", padx=30,pady=30,background = "white")
config_frame.grid(column=0, row=2, sticky=(N, W))
button_frame = Label(content, borderwidth=5, relief="sunken", padx=30,pady=30,background = "orange")
button_frame.grid(column=1, row=2, sticky=(S, E))

title_entry = Entry(title_frame, background="lightblue")
title_entry.grid(column=1, row=0)
title_label = Label(title_frame,text = "Page title",background = "white")
title_label.grid(column=0,row=0)

body_text = Text(body_frame, background="lightblue")
body_text.grid(column=1,row=0)
body_label = Label(body_frame,text = "Page body content",background = "white")
body_label.grid(column=0, row=0)

header_entry = Entry(config_frame, background="lightblue")
header_entry.grid(column=1, row=0)
header_label = Label(config_frame,text = "header",background = "white")
header_label.grid(column=0,row=0)

footer_entry = Entry(config_frame, background="lightblue")
footer_entry.grid(column=1, row=1)
footer_label = Label(config_frame,text = "footer",background = "white")
footer_label.grid(column=0,row=1)

postBtn = Button(button_frame, text="Post")
postBtn.grid(row=0, column=0)
exitBtn = Button(button_frame, text="Exit")
exitBtn.grid(row=0, column=1)

它显示:Tkinter output

关于您的代码无效的原因: 我想这是因为你用以下方式定义了网格位置:

postTtlLbl = Label(postTtlFrame, text="Page title:").grid(row=0, column=0)

而不是

 postTtlLbl = Label(postTtlFrame, text="Page title:")
 postTtlLbl.grid(row=0, column=0)

当您希望创建框架的实例时(通过将实例返回到postTtlLbl变量),这是一个问题,因为网格方法不返回任何内容,因此处理框架的这些变量是{{1你无法用它们做任何事情。

希望很清楚。