1

I am trying to center some text on a canvas, during program initialization. However, winfo_width/height don't return the correct values for me in this case, so I cannot properly place text using Canvas method create_text(), since I cannot calculate the correct center position. I can only get the correct dimensions post-init, say if I query the size in a button callback.

How to solve this? Here's the code:

try:
    from Tkinter import *
except ImportError:
    from tkinter import *

class GUI:
    def __init__(self):
        # root window of the whole program
        self.root = Tk()
        self.root.minsize(800, 600)

        # canvas/viewport for displaying the image and drawing vectors on it
        self.viewport = Canvas(self.root, bd=2, relief='ridge', highlightthickness=0)

        # define master buttons for audio preview, render to file and clear all vectors
        btn_preview = Button(self.root, text='Preview', command=self.Preview)

        # layout managing
        self.viewport.grid(columnspan=3, padx=5, pady=5, sticky=N+S+W+E)
        btn_preview.grid(row=1, padx=85, pady=10, ipadx=5, ipady=5, sticky=W)

        # position text on canvas to notify user he can load the image by clicking it
        self.viewport.update_idletasks()
        textpos = (self.viewport.winfo_width(),self.viewport.winfo_height())
        print(textpos)
        self.viewport.create_text(textpos[0] / 2, textpos[1] / 2, text="Click here to load an image!", justify='center', font='arial 20 bold')

        # weights of rows and columns
        self.root.rowconfigure(0, weight=1)
        self.root.columnconfigure(0, weight=1)

    def Preview(self, event=None):
        textpos = (self.viewport.winfo_width(),self.viewport.winfo_height())
        print(textpos)

if __name__ == '__main__':
    mainwindow = GUI()
    mainloop()

Compare the dimensions returned on init to dimensions after you click the Preview button. They're different!

Mario Krušelj
  • 653
  • 1
  • 6
  • 20

1 Answers1

1

OK haha, I managed to solve it after checking this answer. I needed to bind <Configure> event to the canvas, and define a function that does stuff when window is resized. It's working now!

try:
    from Tkinter import *
except ImportError:
    from tkinter import *

class GUI:
    textid = 0

    def __init__(self):
        # root window of the whole program
        self.root = Tk()
        self.root.minsize(800, 600)

        # canvas/viewport for displaying the image and drawing vectors on it
        self.viewport = Canvas(self.root, bd=2, relief='ridge', highlightthickness=0)

        # define master buttons for audio preview, render to file and clear all vectors
        btn_preview = Button(self.root, text='Preview', command=self.Preview)

        # layout managing
        self.viewport.grid(columnspan=3, padx=5, pady=5, sticky=N+S+W+E)
        btn_preview.grid(row=1, padx=85, pady=10, ipadx=5, ipady=5, sticky=W)

        # weights of rows and columns
        self.root.rowconfigure(0, weight=1)
        self.root.columnconfigure(0, weight=1)

        # bind mouse actions for the canvas
        self.viewport.bind('<Configure>', self.ResizeCanvas)

    def Preview(self, event=None):
        textpos = (self.viewport.winfo_width(),self.viewport.winfo_height())
        print(textpos)

    def ResizeCanvas(self, event):
        if self.textid != 0:
            event.widget.delete('openfiletext')
        # position text on canvas to notify user he can load the image by clicking it
        textpos = (self.viewport.winfo_width(), self.viewport.winfo_height())
        self.textid = self.viewport.create_text(textpos[0] / 2, textpos[1] / 2, text="Click here to load an image!", justify='center', font='arial 20 bold', tag='openfiletext')


if __name__ == '__main__':
    mainwindow = GUI()
    mainloop()
Community
  • 1
  • 1
Mario Krušelj
  • 653
  • 1
  • 6
  • 20