如何在pythontkinter类项目中配置网格管理框架中的行/列大小

2024-09-22 16:29:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用Tkinter和类在python中创建GUI,但是在网格打包程序中调整特定行的大小时遇到了困难。在

我所附的代码工作,但我想控制行宽度,以便顶部2帧是静态的大小和底部的大小与窗口大小。我尝试了很多方法,同时引用了不同的解决方案,但没有任何效果。在

# !/usr/bin/python3

# Use Tkinter for python 2, tkinter for python 3
import tkinter as tk

# Main Window
class WinMain(tk.Frame):
    def __init__(self, master):
        # parameters that you want to send through the Frame class. 
        tk.Frame.__init__(self, master)

        # reference to the master widget, which is the tk window
        self.master = master

        # with that, we want to then run init_window, which doesn't yet exist
        self.init_window()

    def init_window(self):
        # changing the title of our master widget      
        self.master.title("GUI Tester")

        # Create menu for window
        self.createMenu()

        # Create Gui for window
        self.createGui()

        # Update Gui every second after 1 second
        self.after(1000, self.upDateGui)

    def createMenu(self):
        # Initialise drop-down menu
        menu = tk.Menu(self.master)
        self.master.config(menu=menu)

        # Add drop-down menu for Options
        options = tk.Menu(menu, tearoff=False)
        menu.add_cascade(label="Options", menu=options)
        options.add_command(label="Open...", command=self.menuOptionsOpen)
        options.add_separator()
        options.add_command(label="Close", command=self.menuOptionsClose)

        # Add drop-down menu for Help
        help = tk.Menu(menu, tearoff=False)
        menu.add_cascade(label="Help", menu=help)
        help.add_command(label="About...", command=self.menuHelpAbout)

    def createGui(self):
        # Define GUI using Grid to place widgets
        # Size window to its minimum set to 2/3 of the screen resolution
        top = self.winfo_toplevel()

        screen_width = top.winfo_screenwidth()
        screen_height = top.winfo_screenheight()
        screen_resolution = str(int(screen_width * 2 / 3)) + 'x' + str(int(screen_height * 2 / 3))

        top.geometry(screen_resolution)
        top.minsize(int(screen_width * 1 / 3), int(screen_height * 1 / 3))

        # ------------------------------------------------
        # create all frames
        # ------------------------------------------------
        self.c = self.master
        self.c.frameTop = tk.LabelFrame(self.c, text="Top", width=5, height=5, padx=5, pady=5)
        self.c.frameMiddle = tk.LabelFrame(self.c, text="Middle", width=5, height=5, padx=5, pady=5)
        self.c.frameBottom = tk.LabelFrame(self.c, text="Bottom", width=5, height=5, padx=5, pady=5)
        self.c.frameRight = tk.Frame(self.c, borderwidth=5, relief=tk.GROOVE)

        # ------------------------------------------------
        # Create widgets for frameTop
        # ------------------------------------------------
        # Text Box
        self.c.frameTop.textBox = tk.Text(self.c.frameTop, borderwidth=3, relief=tk.SUNKEN)
        self.c.frameTop.textBox.config(font=("consolas", 12), undo=True, wrap='none')

        # Text Box Scroll Bars
        self.c.frameTop.textBoxYScroll = tk.Scrollbar(self.c.frameTop, orient=tk.VERTICAL,
                                                      command=self.c.frameTop.textBox.yview)
        self.c.frameTop.textBox['yscrollcommand'] = self.c.frameTop.textBoxYScroll.set

        self.c.frameTop.textBoxXScroll = tk.Scrollbar(self.c.frameTop, orient=tk.HORIZONTAL,
                                                      command=self.c.frameTop.textBox.xview)
        self.c.frameTop.textBox['xscrollcommand'] = self.c.frameTop.textBoxXScroll.set
        # ------------------------------------------------
        # Create widgets for frameMiddle
        # ------------------------------------------------
        # Text Box
        self.c.frameMiddle.textBox = tk.Text(self.c.frameMiddle, borderwidth=3, relief=tk.SUNKEN)
        self.c.frameMiddle.textBox.config(font=("consolas", 12), undo=True, wrap='none')

        # Text Box Scroll Bars
        self.c.frameMiddle.textBoxYScroll = tk.Scrollbar(self.c.frameMiddle, orient=tk.VERTICAL,
                                                         command=self.c.frameMiddle.textBox.yview)
        self.c.frameMiddle.textBox['yscrollcommand'] = self.c.frameMiddle.textBoxYScroll.set

        self.c.frameMiddle.textBoxXScroll = tk.Scrollbar(self.c.frameMiddle, orient=tk.HORIZONTAL,
                                                         command=self.c.frameMiddle.textBox.xview)
        self.c.frameMiddle.textBox['xscrollcommand'] = self.c.frameMiddle.textBoxXScroll.set
        # ------------------------------------------------
        # Create widgets for frameBottom
        # ------------------------------------------------
        # Text Box
        self.c.frameBottom.textBox = tk.Text(self.c.frameBottom, borderwidth=3, relief=tk.SUNKEN)
        self.c.frameBottom.textBox.config(font=("consolas", 12), undo=True, wrap='none')

        # Text Box Scroll Bars
        self.c.frameBottom.textBoxYScroll = tk.Scrollbar(self.c.frameBottom, orient=tk.VERTICAL,
                                                         command=self.c.frameBottom.textBox.yview)
        self.c.frameBottom.textBox['yscrollcommand'] = self.c.frameBottom.textBoxYScroll.set

        self.c.frameBottom.textBoxXScroll = tk.Scrollbar(self.c.frameBottom, orient=tk.HORIZONTAL,
                                                         command=self.c.frameBottom.textBox.xview)
        self.c.frameBottom.textBox['xscrollcommand'] = self.c.frameBottom.textBoxXScroll.set
        # ------------------------------------------------
        # Create widgets for frameRight
        # ------------------------------------------------
        self.c.frameRight.btnStatus = tk.Button(self.c.frameRight, text='Status Window', command=self.launchWinStatus)
        self.c.frameRight.btnSpare1 = tk.Button(self.c.frameRight, text='Send Middle', command=self.btnSpare1)
        self.c.frameRight.btnSpare2 = tk.Button(self.c.frameRight, text='Spare 2', command=self.btnSpare2)

        # ------------------------------------------------

        # ------------------------------------------------
        # Layout widgets in frameTop
        # ------------------------------------------------
        self.c.frameTop.grid_columnconfigure(0, weight=1)
        self.c.frameTop.grid_columnconfigure(1, weight=0)
        self.c.frameTop.grid_rowconfigure(0, weight=1)
        self.c.frameTop.grid_rowconfigure(1, weight=0)

        self.c.frameTop.textBox.grid(row=0, column=0, sticky="nsew")
        self.c.frameTop.textBoxYScroll.grid(row=0, column=1, sticky="nsew")
        self.c.frameTop.textBoxXScroll.grid(row=1, column=0, sticky="nsew")
        # ------------------------------------------------
        # Layout widgets in frameMiddle
        # ------------------------------------------------
        self.c.frameMiddle.grid_columnconfigure(0, weight=1)
        self.c.frameMiddle.grid_columnconfigure(1, weight=0)
        self.c.frameMiddle.grid_rowconfigure(0, weight=1)
        self.c.frameMiddle.grid_rowconfigure(1, weight=0)

        self.c.frameMiddle.textBox.grid(row=0, column=0, sticky="nsew")
        self.c.frameMiddle.textBoxYScroll.grid(row=0, column=1, sticky="nsew")
        self.c.frameMiddle.textBoxXScroll.grid(row=1, column=0, sticky="nsew")
        # ------------------------------------------------
        # Layout widgets in frameBottom
        # ------------------------------------------------
        self.c.frameBottom.grid_columnconfigure(0, weight=1)
        self.c.frameBottom.grid_columnconfigure(1, weight=0)
        self.c.frameBottom.grid_rowconfigure(0, weight=1)
        self.c.frameBottom.grid_rowconfigure(1, weight=0)

        self.c.frameBottom.textBox.grid(row=0, column=0, sticky="nsew")
        self.c.frameBottom.textBoxYScroll.grid(row=0, column=1, sticky="nsew")
        self.c.frameBottom.textBoxXScroll.grid(row=1, column=0, sticky="nsew")
        # ------------------------------------------------
        # Layout widgets in frameRight
        # ------------------------------------------------
        self.c.frameRight.grid_columnconfigure(0, weight=0)
        self.c.frameRight.grid_rowconfigure(0, weight=0)

        self.c.frameRight.btnStatus.grid(row=0, column=0, sticky="nsew")
        self.c.frameRight.btnSpare1.grid(row=2, column=0, sticky="nsew")
        self.c.frameRight.btnSpare2.grid(row=3, column=0, sticky="nsew")
        # ------------------------------------------------
        # Layout frames in top container
        # ------------------------------------------------
        numOfCols = 2
        numOfRows = 6

        self.c.grid_columnconfigure(0, weight=1, pad=3)
        self.c.grid_columnconfigure(1, weight=0, pad=3)

        self.c.grid_rowconfigure(0, weight=1, pad=3)
        self.c.grid_rowconfigure(1, weight=1, pad=3)
        self.c.grid_rowconfigure(2, weight=1, pad=3)
        self.c.grid_rowconfigure(3, weight=1, pad=3)
        self.c.grid_rowconfigure(4, weight=1, pad=3)
        self.c.grid_rowconfigure(5, weight=1, pad=3)

        frameTopRowCol = [0, 0]
        frameTopSpan = [2, 1]

        frameMiddleRowCol = [frameTopRowCol[0] + frameTopSpan[0],
                             frameTopRowCol[1]]
        frameMiddleSpanRC = [2, 1]

        frameBottomRowCol = [frameMiddleRowCol[0] + frameMiddleSpanRC[0],
                             frameMiddleRowCol[1]]
        frameBottomSpanRC = [2, 1]

        frameRightRowCol = [frameTopRowCol[0],
                            frameTopRowCol[1] + frameTopSpan[1]]
        frameRightSpanRC = [numOfRows, 1]

        self.c.frameTop.grid(row=frameTopRowCol[0], column=frameTopRowCol[1],
                             rowspan=frameTopSpan[0], columnspan=frameTopSpan[1], sticky="nsew")
        self.c.frameMiddle.grid(row=frameMiddleRowCol[0], column=frameMiddleRowCol[1],
                                rowspan=frameMiddleSpanRC[0], columnspan=frameMiddleSpanRC[1], sticky="nsew")
        self.c.frameBottom.grid(row=frameBottomRowCol[0], column=frameBottomRowCol[1],
                                rowspan=frameBottomSpanRC[0], columnspan=frameBottomSpanRC[1], sticky="nsew")
        self.c.frameRight.grid(row=frameRightRowCol[0], column=frameRightRowCol[1],
                               rowspan=frameRightSpanRC[0], columnspan=frameRightSpanRC[1], sticky="nsew")

        # ------------------------------------------------
        # Layout top container in window
        # ------------------------------------------------
        self.grid_columnconfigure(0, weight=1, pad=3)
        self.grid_rowconfigure(1, weight=1, pad=3)

        # ------------------------------------------------
        # Layout window
        # ------------------------------------------------
        top.grid_columnconfigure(0, weight=1, pad=3)
        top.grid_rowconfigure(1, weight=1, pad=3)

    def menuOptionsOpen(self):
        print("menuOptionsOpen")

    def menuOptionsClose(self):
        print("menuOptionsClose")

    def menuHelpAbout(self):
        print("menuHelpAbout")

    def launchWinStatus(self):
        print ("launchWinStatus")

    def btnSpare1(self):
        print("btnSpare1")

    def btnSpare2(self):
        print("btnSpare2")

    def upDateGui(self):
        print("upDateGui")

        # Perform update every x milliseconds
        self.after(1000, self.upDateGui)

# Main
def main():
    root = tk.Tk()
    app = WinMain(root)
    root.mainloop()

# Launch Main
if __name__ == '__main__':
    main()

我在第174行有一节可以更改rowconfigure权重,这有我无法解释的特殊效果。它应该能够固定一些行的高度,而其他行可以随着窗口减小到最小大小而增长/收缩。在


Tags: selfcolumncommandtkgridrowweightsticky
1条回答
网友
1楼 · 发布于 2024-09-22 16:29:30

有几件事:

有很多代码与问题无关。在

您已经构建了一个令人困惑的小部件层次结构。类WinMain() 以根作为主节点实例化。当WinMain()继承{}时, 你从来没有在self里面放任何小工具。然后创建名称top = self.winfo_toplevel(),它是正在运行的Tk()实例=root=master=self.master=self.c。在

你对符号的使用令人困惑

self.c.frameTop.textBox = tk.Text(self.c.frameTop, ...

为什么在frameTop的textBox属性中保存对文本小部件的引用?在

最后在self(不包含任何内容的框架)中配置网格 和root。在

我认为你的很多问题是因为你混淆了事物的名称。我在下面提供一个示例,其中只提供了获得正确行为所需的代码。我使用bg颜色是为了便于识别不同的小部件。在

^{pr2}$

相关问题 更多 >