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!
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()