Tkinter — how to horizontally center canvas text?

Question:

I’m working on a function in a UI class that is a config window, it displays the logo of the program and has an updating text at the bottom telling you what it’s loading, etc. This is what I have so far:

    self.window = "config"
    self.windowWidth = 340
    self.windowHeight = 270
    infoText = "Configuring Kh..."
    self.root = tk.Tk()
    self.root.geometry("%dx%d+400+400" % (self.windowWidth, self.windowHeight))
    self.root.title("Kh Control v1.1 starting...")
    logo = tk.PhotoImage(file="KhLogo.gif")
    mainPanel = tk.Canvas(self.root, width=self.windowWidth, height=self.windowHeight)
    mainPanel.image = logo
    mainPanel.pack()
    mainPanel.create_image(0, 0, image=logo, anchor="nw")
    mainPanel.create_text(0,200, text=infoText, anchor="nw", fill="yellow")
    return

I’d like the text in infoText to be centered horizontally and offset vertically about 200px down. The vertical offset works fine, but I can’t figure out how to center the text horizontally.

I started by trying the age old ((width / 2) – (str length / 2)) but then realized that each letter isn’t 1px. And anchor = “center” seems to only put half the text off the left side of the screen.

I’m very new to Python (only a few days now) so if I’m missing something obvious, that’s why.

EDIT: and in case it wasn’t obvious, this text will change so I can’t just make an absolute decision on the offsets, it has to change with the text

Asked By: linus72982

||

Answers:

Have you tried using the justify parameter?
Often center is used with non-text objects.

https://stackoverflow.com/a/15016161/3900967 might provide some insight.

Answered By: ccpmark

I figured it out after scrounging through the canvas reference.

There is a method for a canvas called bbox that returns a tuple containing (x1, y1, x2, y2) of the area an item takes up. I got those coords, drew up a function to find the px length of it, divided it by 2 and subtracted it from the window width. Then I used canvas.move to change the x offset using the number the function returned.

    def findXCenter(self, canvas, item):
      coords = canvas.bbox(item)
      xOffset = (self.windowWidth / 2) - ((coords[2] - coords[0]) / 2)
      return xOffset

The main part is here:

    textID = mainPanel.create_text(0,0, text=infoText, anchor="nw", fill="yellow")
    xOffset = self.findXCenter(mainPanel, textID)
    mainPanel.move(textID, xOffset, 0)

Hopefully my hours of searching for this answer will help someone later on.

Answered By: linus72982

You can set the position of the text using the first part of the .create_text() method.
see http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/create_text.html

To make this position horizontialy center to the window use self.windowWidth / 2 as the x cordinate

By default the text is anchored to center around the given position.
(.create_text will default to anchor=”CENTER”)

You will also want to remove the anchor=”nw” as this will make your text display down and to the right of the position given

As such your updated code should be.

self.window = "config"
self.windowWidth = 340
self.windowHeight = 270
infoText = "Configuring Kh..."
self.root = tk.Tk()
self.root.geometry("%dx%d+400+400" % (self.windowWidth, self.windowHeight))
self.root.title("Kh Control v1.1 starting...")
logo = tk.PhotoImage(file="KhLogo.gif")
mainPanel = tk.Canvas(self.root, width=self.windowWidth, height=self.windowHeight)
mainPanel.image = logo
mainPanel.pack()
mainPanel.create_image(0, 0, image=logo, anchor="nw")
mainPanel.create_text(self.windowWidth/2,200, text=infoText, fill="yellow")
return
Answered By: Daniel Stewart

You can use the anchor="center" method to align your text that created inside the canvas using canvas.create_text method

try following example code:

from tkinter import *

root = Tk()

canvas = Canvas(root, width=400, height=300)
canvas.pack()

text = canvas.create_text(200, 150, text="Hello World!", anchor="center")

root.mainloop()
Answered By: Sasindu Senanayake
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.