[tkinter] How do I vertically center text to window in GUI?

Hello, I’m new to using tkinter and I am attempting to center the text in the GUI to always be vertically center of the window. Currently the text is center to the left of the canvas. I cant tell whether its the frame or label that needs the code change but what I’ve tried so far has not worked.

Can anyone help me figure out which part(s) I need to change?

import tkinter as tk

root = tk.Tk()
root.title("Class Display")
root.geometry("400x400")
root.configure(bg='red')

scrollbar = tk.Scrollbar(root)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

canvas = tk.Canvas(root, width=300, height=400, bg='white', highlightthickness=0)
canvas.pack(fill="both", expand=True, pady=30, padx=30)

# Add a frame on the canvas to hold labels (as labels themselves can't scroll)
frame = tk.Frame(canvas, bg='white')
canvas.create_window((0, 0), window=frame, anchor='center')

# Configure the scrollbar to scroll the canvas window
scrollbar.config(command=canvas.yview)
canvas.config(yscrollcommand=scrollbar.set)

for i in range(50):
    label = tk.Label(frame, text="Hello Silly", fg="Pink", font=("Helvetica", 16))
    label.pack(fill=tk.BOTH, anchor='center')  # Center each label

frame.update_idletasks()  # Update the frame to fit all labels
canvas.config(scrollregion=canvas.bbox("all"))  # Update the scroll region to include all items

root.mainloop()

Edit: I found a soultion. I replaced canvas.create_window((0, 0), window=frame, anchor='nw') with

    def center_frame(event=None):
        canvas.create_window((canvas.winfo_width() // 2, 0), window=frame, anchor='n')  # Anchor to the top of the canvas
        canvas.config(scrollregion=canvas.bbox("all"))  # Update the scroll region after centering
  # Update the scroll region after centering

# Bind the <Configure> event to update the frame's position on window resize
    canvas.bind("<Configure>", center_frame)

Hi,

do you mean like this?

I was hoping for something more like this (photoshop mockup)

Note that your canvas has geometry values of width = 300 and height = 400.

The “width” corresponds to the x coordinate. Your value for padx is set to 30 (near the beginning of the x-coordinate). The half-way point of 300 is 150. So, set padx = 150 or something less than this since you have to take into account the width and starting point of the text which is not zero (0).

That only centers the text by increase the padding and force the label into the center. I want to center the text without increasing the padding similar to the above Photoshop mock up

how about this:

Here:

https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/create_window.html

It says for the create_window method:

width	The width of the area reserved for the window. If omitted, the window will be sized to fit the width of the contained widget.

You haven’t specified the width of the frame that’s on the canvas, and you placed it at (0, 0).

Therefore, it’s at the top-left of the canvas and it’s only as wide as the labels on it.

Yes, that looks great. Can you tell me what you changed in the code

I just modified the width of the canvas window from its default value is all and kept the original value of the canvas.pack padx = 30 value.

canvas.create_window((0, 0), window=frame, anchor='center', width=325)

That didn’t exactly work. The label athough looks center inits 400x400 ascpet ratio the label or frame or canvas(IDK which) is not actually centered

import tkinter as tk

root = tk.Tk()
root.title("Class Display")
root.geometry("400x400")
root.configure(bg='red')

scrollbar = tk.Scrollbar(root)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

canvas = tk.Canvas(root, width=300, height=400, bg='white', highlightthickness=0)
canvas.pack(fill="both", expand=True, pady=30, padx=30)

# Add a frame on the canvas to hold labels (as labels themselves can't scroll)
frame = tk.Frame(canvas, bg='white')
canvas.create_window((0, 0), window=frame, anchor='center', width=325)

# Configure the scrollbar to scroll the canvas window
scrollbar.config(command=canvas.yview)
canvas.config(yscrollcommand=scrollbar.set)

for i in range(50):
    label = tk.Label(frame, text="Hello Silly", fg="Pink", font=("Helvetica", 16))
    label.pack(fill=tk.BOTH, anchor='center')  # Center each label

frame.update_idletasks()  # Update the frame to fit all labels
canvas.config(scrollregion=canvas.bbox("all"))  # Update the scroll region to include all items

root.mainloop()

Don’t click on the maximize widget to expand the window since you specifically created it with dimensions of 400 x 400.

That does not center the text to the window like I had hoped

Hi !

Simply don’t use a Canvas if you don’t need to. Canvas is a great tool for displaying images, drawings, geometrical shapes, etc., but not for handling text. It is more intended for displaying static scenes, hence your problem for dynamically centering.

For displaying text and having it gracefully resize and recenter, you should instead use a Label or a Text widget.