Home > database >  How to achieve complex layouts with Tkinter?
How to achieve complex layouts with Tkinter?

Time:09-09

I would like to achieve this layout with Tkinter but I don't really understand how Tkinter layout works...

Layout needed

The footer has a top/bottom padding, so the height is "fixed" and the buttongroup should be centered horizontally. The Image2 has a fixed width and takes the all remaining height. The Image 1 takes all the remaining space. (the window should be resizable)

So, I have two main trouble to achieve this :

  1. How to place the bottom buttongroup to be centred, horizontally-distribued, and sticking the bottom ?
  2. How to make the Image1 expand to the remaing space (I'm currently using the tecnique with the empty Label widget with a PIL ImageTk.PhotoImage to display the images) ?

More generally, if I can see a full exemple to achieve this, I think I will much more undertand Tkinter layouts (for now, I'm quite lost...)

Here is the best code I achieved :

import tkinter as tk
from tkinter import Button, Label, Frame
from PIL import Image, ImageTk

# configure root
root = tk.Tk()
root.title('app')
root.geometry('800x600')

# images
main_frame = Frame(root)
main_frame.pack(expand=1, fill='both')
image_path = 'C:/Users/Administrator/Desktop/sample_image.jpg'
image = ImageTk.PhotoImage(Image.open(image_path))
image1 = Label(main_frame, text='image1', image=image,
               bg='red').pack(side='left', expand=1, fill='both')
image2 = Label(main_frame, text='image2', image=image, width=250,
               bg='green').pack(side='left', fill='both')

# buttons
footer_frame = Frame(root, pady=5)
Button(footer_frame, text='Positif').pack(side='left', padx=2)
Button(footer_frame, text='Indéterminé').pack(side='left', padx=2)
Button(footer_frame, text='Négatif').pack(side='left', padx=2)
footer_frame.pack(side='bottom')

root.mainloop()

But I've got issues with the size of image1 (when the windows size is less than the image size, it hides the buttons or the image2.

CodePudding user response:

Note that the order of packing widgets matters:

  • pack footer_frame before main_frame
  • pack image2 before image1

Below is the updated code:

import tkinter as tk
from tkinter import Button, Label, Frame
from PIL import Image, ImageTk

# configure root
root = tk.Tk()
root.title('app')
root.geometry('800x600')

# images
main_frame = Frame(root)
image_path = 'C:/Users/Administrator/Desktop/sample_image.jpg'
image = ImageTk.PhotoImage(Image.open(image_path))

# pack image2 before image1
image2 = Label(main_frame, text='image2', image=image, width=250,
               bg='green').pack(side='right', fill='y')
image1 = Label(main_frame, text='image1', image=image,
               bg='red').pack(side='left', expand=1, fill='both')

# buttons
footer_frame = Frame(root, pady=5)
Button(footer_frame, text='Positif').pack(side='left', padx=2)
Button(footer_frame, text='Indéterminé').pack(side='left', padx=2)
Button(footer_frame, text='Négatif').pack(side='left', padx=2)

# pack footer_frame before main_frame
footer_frame.pack(side='bottom')
main_frame.pack(expand=1, fill='both')

root.mainloop()
  • Related