首页 文章

如何在已经打包到左侧的现有小部件下面打包tkinter小部件?

提问于
浏览
7

我正在尝试编写一个基本的Tkinter GUI,其顶部有一个 Text 小部件,然后在它下面对齐一个 Button 小部件,然后按钮下面的另一个小部件 . 我遇到的问题是,在将 Button 小部件打包到左侧后,当我再打包第二个 Text 小部件时,它将它放在右边的按钮旁边,而不是按钮下方 . 无论我为第二个 Text 小部件设置 side 参数,都会发生这种情况 . 这是一段演示此行为的简单代码:

from Tkinter import *

root = Tk()

w = Text(root)
w.pack()

x = Button(root, text="Hi there!")
x.pack(side=LEFT)

y = Text(root)
y.pack(side=BOTTOM)

root.mainloop()

那么我将如何设置第二个 Text 小部件,使其显示在按钮下方而不是右侧?

4 回答

  • 0

    布局问题通常有两种解决方案:

    • 切换到使用网格 . 像你想要完成的那样做布局真的很容易 . 网格可以解决所有布局问题的95%(当你想到它时,这是惊人的 - Tk与一位经理一起做大多数工具包需要六个人来完成!)

    • 使用多个帧 . 如果某些小部件需要从上到下堆叠,而某些小部件需要从左到右堆叠,您无法始终获得所需的内容,将所有内容打包在一个框架中 . 对于布局的从上到下部分使用一个框架,对于从左到右的内容使用附加框架 .

    还要意识到小部件不一定是打包/网格化的小部件的子节点 . 您可以使用“in”参数将窗口小部件放在除父窗口之外的其他容器中 .

    例如,在您的特定示例中,您可以创建三个框架,顶部,中部,底部 . 在顶层窗口中将这些从上到下打包 . 然后,您可以将顶部的第一个文本小部件,中间的水平按钮或按钮打包,并将底部的另一个文本小部件打包 .

    这种方法的优势在于它使未来更改布局变得更加容易(根据我的经验总是在某些时候发生) . 您不必重新设置任何窗口小部件,只需在其他容器中打包/放置/网格化即可 .

    在您的简短示例中,它没有太大区别,但对于复杂的应用程序,这种策略可以节省生命 .

    我最好的建议是:布局不是事后的想法 . 做一点计划,甚至花五分钟画一些方格纸 . 首先确定应用程序的主要区域,并为每个区域使用框架或其他容器(paned窗口,笔记本等) . 一旦你拥有了这些,就为每个部分做同样的分而治之的方法 . 这使您可以为应用的不同部分使用不同类型的布局 . 工具栏获得水平布局,表单可能获得垂直布局等 .

  • 14

    我最初误解了包装是如何工作的,并没有意识到整个左侧是"claimed"当我做了 x.pack(side=LEFT) . 我在阅读this后得到的结果是亚历克斯在这里得到的答案是,我根本没有把 x 打包到左侧,而是让它 anchored 在左边,使用 anchor=W (W代表West)代替 side=LEFT . 我修改后的代码片段完成了我的工作,如下所示:

    from Tkinter import *
    
    root = Tk()
    
    w = Text(root)
    w.pack()
    
    x = Button(root, text="Hi there!")
    x.pack(anchor=W)
    
    y = Text(root)
    y.pack(side=BOTTOM)
    
    root.mainloop()
    

    这样, x 不再是左侧,它只是在其空间块内与左侧(或西侧)对齐 .

  • 7

    打包按照调用.pack方法的顺序进行,所以一旦x“声明”了左侧,就是它 - 它将占据其父节点的左侧部分,而其父节点中的所有其他内容将位于其右侧 . 你需要一个框架来“调解”,例如......:

    from Tkinter import *
    
    root = Tk()
    
    w = Button(root, text="Mysterious W")
    w.pack()
    
    f = Frame(root)
    x = Button(f, text="Hi there!")
    x.pack()
    
    y = Button(f, text="I be Y")
    y.pack(side=BOTTOM)
    
    f.pack(side=LEFT)
    
    root.mainloop()
    

    (将文本更改为按钮以便更直接地查看布局 - 此Mac上的Tkinter在获得焦点之前不会清楚地显示文本,但按钮非常清晰;-) .

  • 3

    这与WebView使用Mosaic Canvas Widget Sets内部(与Tk非常相似)的方式相同 . 诀窍是第二个相同的命名帧对象作为块级浮点(内联:块;)用于放置在它之后的所有内容,并且调用“fr”的所有内容都将自动从其内部开始 .

    你可以让很多人做这个TOP对齐的小部件,只需添加另一个相同的命名框架,你想要在side = LEFT之间断开 . 在Bottom之后也可以工作 .

    fr=Frame(root)
    fr.pack(fill=X, side=TOP)
    
    block1=Label(fr)
    block1.pack(side=LEFT)
    
    block2=Label(fr)
    block2.pack(side=LEFT)
    
    block3=Button(fr)
    block3.pack(side=LEFT)
    
    # NAME IT THE SAME ID NAME AS THE FIRST MAIN FRAME...
    fr=Frame(root)
    fr.pack(fill=X, side=TOP)
    
    # These NOW jump into the second Frame breaking the side=LEFT in new Frame
    block4=Label(fr) 
    block4.pack(side=LEFT)
    
    block5=Label(fr)
    block5.pack(side=LEFT)
    
    # AND THEY CONTINUE GOING side=LEFT AFTERWARDS.
    

相关问题