Aman Grover
Aman Grover

Reputation: 1641

Make Tkinter window resize and adjust window contents dynamically

Is it possible to make tkinter window's contents adjust to screen size? Like if I had made a window according to a screen resolution of 1366x768, and then I run the same code on a system of 1024x768 resolution and make its contents resize dynamically? I know I can use grid structure as as described here and set the weight of cells accordingly. But is it possible with pack geometry structure and not grid? I am asking this since half of the project I am working on was made by my colleague and he didn't use grid at all. So instead of redoing all of the code in grid, I am looking for a way around it. Here is the sample code I need to resize -

def container(self):
    frame_number_panel = tk.Frame(self.parent, width=round(Dimension.SCREEN_WIDTH*0.8), height=Dimension.SCREEN_HEIGHT, bg="#eeeeee")
    frame_number_panel.pack(side="left", anchor=W)
    frame_number_panel.pack_propagate(False)
    self.main_container(frame_number_panel)
    
    # right side pannel
    frame_right_side_panel = tk.Frame(self.parent, bg="#101115", width=round(Dimension.SCREEN_WIDTH*0.2), height=Dimension.SCREEN_HEIGHT)
    frame_right_side_panel.pack(side="right", anchor=NE)
    frame_right_side_panel.pack_propagate(False)
    frame_first_row = tk.Frame(frame_right_side_panel, bg="#101115")
    frame_first_row.pack()

    winning_claim_image = PhotoImage(file=ResourcePath.resource_path('images/icon_win_claim.png'))
    label_winning_claim = tk.Label(frame_first_row, bg="#fcd116", text="WINNING\nCLAIM", image=winning_claim_image,
                                   compound="left", fg="#231f20", font=("Roboto-Bold", 10, "bold"),
                                   width=Dimension.label_winning_claim_width,
                                   height=Dimension.label_winning_claim_height)
    label_winning_claim.image = winning_claim_image
    label_winning_claim.pack(side="left", padx=Dimension.label_winning_claim_padx)

    reprint_image = PhotoImage(file=ResourcePath.resource_path('images/reprint_2.png'))
    label_reprint = tk.Label(frame_first_row, bg="#8ac539", text="REPRINT", image=reprint_image,
                             compound="left", fg="#231f20", font=("Roboto-Bold", 10, "bold"),
                             width=Dimension.label_winning_claim_width, height=Dimension.label_winning_claim_height)
    label_reprint.image = reprint_image
    label_reprint.pack(side="left", padx=Dimension.label_winning_claim_padding)

as you can see all the widgets are placed using pack geometry manager.

Upvotes: 1

Views: 3100

Answers (1)

David Duran
David Duran

Reputation: 1826

You can achieve nearly the same with pack than with grid. Indeed, I usually prefer the packing, since it gives me more freedom.

For instance, take the following example:

from tkinter import Tk, Label, X, Frame, Y, LEFT, BOTH

root = Tk()

# Initialize frames
f1 = Frame(root, bg="grey")
f2 = Frame(root, bg="pink")

# Initialize labels
w1 = Label(f1, text="Red", bg="red", fg="white")
w2 = Label(f1, text="Green", bg="green", fg="white")
w3 = Label(f1, text="Blue", bg="blue", fg="white")
w1b = Label(f2, text="Red", bg="red", fg="white")
w2b = Label(f2, text="Green", bg="green", fg="white")
w3b = Label(f2, text="Blue", bg="blue", fg="white")

# Packing level 1
f1.pack(fill=X)
f2.pack(fill=BOTH, expand=True)

# Packing level 2
w1.pack(fill=X)
w2.pack(fill=X)
w3.pack(fill=X)
w1b.pack(side=LEFT, fill=BOTH, expand=True)
w2b.pack(side=LEFT, fill=BOTH, expand=True)
w3b.pack(side=LEFT, fill=BOTH, expand=True)

root.mainloop()

enter image description here

As you can see, by using the parameters fill and expand in the correct way, I have set the second frame to be expandable with the windows on both sides (X and Y), while the first frame is only expandable in X. All the labels inside the frames are also equally distributed.

See all the options of pack in the documentation: https://effbot.org/tkinterbook/pack.htm.

Upvotes: 2

Related Questions