Tkinter canvas resizing automatically Tkinter canvas resizing automatically tkinter tkinter

Tkinter canvas resizing automatically


We've established that highlightthickness, an option of Canvas, is the culprit for this behavior, and setting it to 0 fixes the issue.

Here's why (I think) it happens:

From http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm

ConfigureThe widget changed size (or location, on some platforms). The new size is provided in the width and height attributes of the event object passed to the callback.

This is the stripped down version of the Canvas subclass:

class ResizingCanvas(Canvas):    def __init__(self,parent,**kwargs):        Canvas.__init__(self,parent,**kwargs)        print self.winfo_reqwidth(),self.winfo_reqheight() #>>>854, 404        self.bind("<Configure>", self.on_resize)    def on_resize(self,event):        self.width = event.width   #>>>854        self.height = event.height #>>>404        self.config(width=self.width, height=self.height)

So, <Configure> should operate like this:

  1. Detect resize
  2. Call function
  3. Set Canvas to new size

But it's doing this:

  1. Detect resize
  2. Call function
  3. Set Canvas to new size
  4. Detect resize, repeat

What's happening between 3 & 4? Well, the Canvas is being set to a new size (its previous size + 4), but after that, the highlightthickness changes the actual size to +4 of that, which triggers <Configure> in an endless loop until the screen width is hit and it breaks.

At that point, normal resizing can occur, because it's got just one size to work off of (the combined highlight and canvas size), and it functions normally. If you added a button that resized the canvas and pressed it after the canvas stopped expanding, it would resize, then get weird again and start expanding.

I hope that kind of explained it. I'm not 100% sure that this is 100% correct, so if anyone has corrections, feel free.


I think the original problem is the recursive behaviour of on_resize() which is binding to Configure event, and resize() also calls "self.config(width=self.width, height=self.height)" - which will trigger the Configure event again.Remove "self.config(width=self.width, height=self.height)" will fix the problem.

Apparently setting "highlightthickness=0" also fix the problem - I am guess the window layout manager has some magic detecting there is no change in the window size hence stop calling on_resize() recursively