简体   繁体   中英

tkinter - How to get frames and widgets to fill window?

The two frames in my program, ViewSubjects and AddSubjects both contain frames and widgets that are not stretching to fill the screen. Why are they doing this and how would I go about fixing it?

ViewSubjects Frame

AddSubjects Frame

Here is my code:

import tkinter as tk
from tkinter import ttk
import tkinter.scrolledtext as tks

class Program(tk.Tk):        
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        tk.Tk.iconbitmap(self, default = "")
        tk.Tk.wm_title(self, "")

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}
        for F in (SubjectHome, ViewSubject, AddSubject):

            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row = 0, column = 0, sticky = "nsew")

        self.show_frame(SubjectHome)



    def show_frame(self,cont):
        frame = self.frames[cont]
        frame.tkraise()


class SubjectHome(tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent)

        ttk.Style().configure("TButton", padding=6, relief="flat", background="#ccc")

        name = tk.Label(self, text = "User: FirstName + LastName")
        name.pack(anchor="ne")

        pagename = tk.Label(self, text = "Subject Menu")
        pagename.pack(anchor="n")

        self.innerFrame = tk.Frame(self, bg="red")
        self.innerFrame.place(relx=.5, rely=.5, anchor="c")        


        view = ttk.Button(self.innerFrame, text = "View Subjects", command = lambda: controller.show_frame(ViewSubject))
        view.grid(row=0, sticky="W"+"E")

        add = ttk.Button(self.innerFrame, text = "Add Subjects", command = lambda: controller.show_frame(AddSubject))
        add.grid(row=1, sticky="W"+"E")


class ViewSubject(tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent)

        innerFrame = tk.Frame(self)
        innerFrame.place(relx=.5, rely=.5, anchor="c")

        firstFrame = tk.Frame(innerFrame)
        firstFrame.grid(row=0, sticky="WE")

        secondFrame = tk.Frame(innerFrame)
        secondFrame.grid(row=1, sticky="WE")

        self.text = tks.ScrolledText(firstFrame)
        self.text.grid(rowspan=3, columnspan=3 ,sticky="E")

        scrollbar = tk.Scrollbar(secondFrame, orient="vertical")
        lb = tk.Listbox(secondFrame, yscrollcommand=scrollbar.set)
        scrollbar.config(command=lb.yview)

        scrollbar.pack(side="right", fill="y")
        lb.pack(side="left",fill="both", expand=True)

        for x in range(15):
            lb.insert("end", x)

        back = ttk.Button(innerFrame, text = "Back", command = lambda: controller.show_frame(SubjectHome))
        back.grid(row=2, sticky="W")

        next = ttk.Button(innerFrame, text = "Next")
        next.grid(row=2, sticky="E")

class AddSubject(tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent)

        name = tk.Label(self, text = "User: FirstName + LastName")
        name.pack(anchor="ne")

        pagename = tk.Label(self, text = "Add Subjects")
        pagename.pack(anchor="n")

        self.innerFrame = tk.Frame(self)
        self.innerFrame.place(relx=.5, rely=.5, anchor="c")

        canvas = tk.Canvas(self.innerFrame)

        self.firstFrame = tk.Frame(canvas)
        self.firstFrame.pack(anchor="n")

        info = tk.Label(self.innerFrame, text = "Information...\n Information....")
        info.pack()

        for x in range(5):
            pagename = tk.Label(self.firstFrame, text = "Unit Name")
            pagename.grid(row=0, column=x)
            self.text = tks.ScrolledText(self.firstFrame, width=50)
            self.text.grid(row=1, column=x ,sticky="E")

        scrollbar = tk.Scrollbar(self.innerFrame, orient="horizontal", command=canvas.xview)
        canvas.configure(xscrollcommand=scrollbar.set)
        scrollbar.pack(side="bottom", fill="x")
        canvas.pack(side="left", fill="both", expand=True) 

        back = ttk.Button(self.innerFrame, text = "Back", command = lambda: controller.show_frame(SubjectHome))
        back.pack(anchor="sw")

        next = ttk.Button(self.innerFrame, text = "Next")
        next.pack(anchor="se")


app = Program()
app.state('zoomed')
app.mainloop()

Most of your problems boil down to three common mistakes:

First, you are using place , and place by default doesn't make windows grow or shrink. It assumes you created widgets to be the exact size you want them to be. You need to explicitly tell tkinter how you want it to handle extra space.

In your case you probably want to set the relative width and relative height of the inner frames to 1.0 (ie: 100% of the width and height of the containing window) with the relwidth and relheight options. This will force the inner frame to always be exactly as tall and wide as its parent.

self.innerFrame.place(..., relwidth=1.0, relheight=1.0)

Second, you are using grid within the inner frames, but you are failing to give any rows or columns a weight. The weight tells tkinter how to allocate extra space. By default, extra space goes unused. Since you want your widgets to fill the extra space, you need to give at least one row and one column a positive weight.

Third, you're trying to solve too many problems at once. My advice is to remove all of the widgets except one frame. Get it to fill, grow and shrink the way you want. Then, add its immediate children and do likewise. Then, add any grandchildren, and continue on, one group of widgets at a time, until you're satisfied with that frame. Only then should you move on and fix another frame.

protip: give each frame a unique color during development. This makes it easy to see which frames are growing or shrinking, and which ones are not.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM