1

I try to have a tkinter.Frame that have a full screen image and some buttons underneath it

WIDTH, HEIGHT = 800, 600

root = Tk()

mainframe = Frame(root, padding="3 3 12 12")
mainframe.pack(fill=BOTH, expand=True)

infovariable = StringVar()
infovariable_label = Label(mainframe, textvariable=infovariable, anchor=S)
infovariable_label.pack(fill=X, side=TOP)

label = Label(mainframe)
label.pack(fill=BOTH, expand=True) 

image_base = Image.open('hello.jpg')

# setting the photo
image = (image_base
         .resize(2500, 1000)
         .crop(0, 0, WIDTH,HEIGHT))

label.configure(image=photo)

When I do a window resize, I want my photo to be the same dimensions (width/height), if I do that:

def onResize(event):
    global WIDTH, HEIGHT
    WIDTH = event.width
    HEIGHT = max(0, event.height - 50)

    # setting the photo
    image = (image_base
             .resize(2500, 1000)
             .crop(0, 0, WIDTH,HEIGHT))

root.bind('<Configure>', onResize)

The resize, makes the image change size, then call the resize again, having a window that infinitely resizes.

I have the same problem as this thread:

odd behavior with '<Configure>' callback

Robert Vanden Eynde
  • 681
  • 1
  • 7
  • 18

1 Answers1

2

When you bind to the root window, that binding applies to every child of the root window, too, due to how tkinter uses binding tags.

Part of the solution is to change your onResize to only change the size of the image if the event.widget represents the root window. There may be other problems, but that's the first.

You also need to make sure you account for borders. If you make the image the same size of the window, but the label has a one pixel border, that will cause the label to grow, which will cause the root window to grow, which will start the process all over again.

Another answer related to bind tags is here: https://stackoverflow.com/a/2472992/7432

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • I wouldn't want to calculate the border and the hierarchy of the gui (applying border and padding to each children). Isn't there a way to get a full width widget that has an image automatically the width of the container ? – Robert Vanden Eynde Dec 14 '17 at 02:35
  • The hierarchy of bindings is also why you sometimes see `return "break"` in an event handler. The "break" string breaks out of the binding hierarchy. – GaryMBloom Dec 14 '17 at 03:54
  • @RobertVandenEynde: no. Tkinter images don't work that way. You have to do what you are doing - detect changes in the size of the widget, compute the correct size, and then force the image to resize. – Bryan Oakley Dec 14 '17 at 12:23
  • Turned out I used a Canvas that just draws one image instead of a Label. It has the property I want (resizes when the window resizes). But I'm still wondering if there is a css "max-width: 100%" equivalent. – Robert Vanden Eynde Dec 15 '17 at 13:11
  • @RobertVandenEynde: no, there is not a "max-width" equivalent for images. Widgets, yes, images, no. – Bryan Oakley Dec 15 '17 at 13:16