Python 如何使用包或网格实现以下Tkinter GUI布局?

Python 如何使用包或网格实现以下Tkinter GUI布局?,python,layout,grid,tkinter,pack,Python,Layout,Grid,Tkinter,Pack,以下是我当前跳棋游戏的GUI布局: 如您所见,它包括顶部的菜单、左侧的画布(我在其中绘制棋盘)、右上角的工具栏(框架),其中有各种格式/导航按钮,以及用于注释移动的文本小部件。目前,我正在为小部件使用网格布局 以下是我需要做的: 当文本量大于小部件大小时,能够在文本小部件中显示/隐藏滚动条。(根据,这似乎需要网格布局。) [通过首选项对话框]更改文本小部件中文本的字体和/或大小,不要在文本小部件周围留下奇怪的间隙。(这似乎需要一个包布局,因为文本小部件只能以字符而不是像素为单位指定宽度和高度…

以下是我当前跳棋游戏的GUI布局:

如您所见,它包括顶部的菜单、左侧的画布(我在其中绘制棋盘)、右上角的工具栏(框架),其中有各种格式/导航按钮,以及用于注释移动的文本小部件。目前,我正在为小部件使用网格布局

以下是我需要做的:

  • 当文本量大于小部件大小时,能够在文本小部件中显示/隐藏滚动条。(根据,这似乎需要网格布局。)
  • [通过首选项对话框]更改文本小部件中文本的字体和/或大小,不要在文本小部件周围留下奇怪的间隙。(这似乎需要一个包布局,因为文本小部件只能以字符而不是像素为单位指定宽度和高度…这意味着当我更改字体或大小时,文本小部件会变大或缩小,窗口不会调整以适应网格布局。我一直在尝试使用font.measure根据字体大小调整文本小部件的大小。)当选,但我仍然会有间隙,因为我无法将小部件的大小调整到精确的像素。)
  • 我的最终解决方案需要跨平台(包括Windows和Linux,希望还有Mac)

  • 我可以使用哪种布局来满足我的要求?如果两者都不能完全发挥作用,那么哪种布局(网格或包)最接近我的目标?谢谢

    对于这个简单的布局,您可以使用
    网格
    或两者兼用。在这种特殊情况下,两者都没有明显的优势。两者都有您想要的调整大小行为

    我会在头顶上用一个水平的框架来固定按钮,然后把按钮装进去。然后我可能会使用网格将工具栏、文本小部件和滚动条放置在一个框架内。包也可以使用,任何一个都可以。那会照顾好右边

    如果你想要菜单栏在图片中的样子(即:非标准,仅在棋盘上方),我会使用类似的技术:另一个框架位于左侧,菜单栏位于顶部,棋盘位于底部

    然后我会在主窗口中使用pack,底部是statusbar,左边是棋盘,右边是文本区域

    但是,最好使用标准菜单栏,这意味着您不需要棋盘/菜单栏组合的包含框架

    这里有一个使用标准菜单栏的快速解决方案。这使用了一种技术,将大多数小部件作为父部件的子部件,然后使用
    in
    参数将它们放入容器中。这使得以后更改布局更加容易,因为您不必更改整个层次结构,只需更改容器中小部件的位置

    import Tkinter as tk
    import random
    
    class App(tk.Tk):
        def __init__(self, *args, **kwargs):
            tk.Tk.__init__(self, *args, **kwargs)
    
            size = 40
            menubar = tk.Menu(self)
            menubar.add_cascade(label="Game")
            menubar.add_cascade(label="Options")
            menubar.add_cascade(label="Help")
            chessboard = tk.Canvas(width=8*size, height=8*size, borderwidth = 0,
                                   highlightthickness=0)
            statusbar = tk.Label(self, borderwidth=1, relief="sunken")
            right_panel = tk.Frame(self, borderwidth = 1, relief="sunken")
            scrollbar = tk.Scrollbar(orient="vertical", borderwidth=1)
            # N.B. height is irrelevant; it will be as high as it needs to be
            text = tk.Text(background="white",width=40, height=1, borderwidth=0, yscrollcommand=scrollbar.set)
            scrollbar.config(command=text.yview)
    
            toolbar = tk.Frame(self)
            for i in range(10):
                b = tk.Button(self, text="B%s" % i, borderwidth=1)
                b.pack(in_=toolbar, side="left")
    
            self.config(menu=menubar)
            statusbar.pack(side="bottom", fill="x")
            chessboard.pack(side="left", fill="both", expand=False)
            toolbar.grid(in_=right_panel, row=0, column=0, sticky="ew")
            right_panel.pack(side="right", fill="both", expand=True)
            text.grid(in_=right_panel, row=1, column=0, sticky="nsew")
            scrollbar.grid(in_=right_panel, row=1, column=1, sticky="ns")
            right_panel.grid_rowconfigure(1, weight=1)
            right_panel.grid_columnconfigure(0, weight=1)
    
    if __name__ == "__main__":
        app = App()
        app.mainloop()
    

    网格布局具有与pack相同的增长/收缩行为,只是访问方式不同(赋予行和/或列“权重”),您的屏幕截图显示了一个非标准菜单栏,该菜单栏不会一直延伸到整个页面。这是一个要求,还是一个标准菜单行吗?布莱恩,谢谢你的帮助。我从来不知道你可以在同一个窗口内混合包装和网格,只要它们在不同的容器中。我也不知道在网格中使用权重。@Brandon:我一直在混合几何管理器。这确实是唯一的工作方式,因为每个人都有自己的长处和短处。把自己限制在一个范围内是。。。UH限制。只是要小心,不要在同一个容器中同时使用网格和包,这是出现问题的时候。