3

I am creating a simple application using tkinter.ttk. I am creating one Image Viewer App but while creating the app I am getting some problem. Here is my code:

from tkinter import *
from tkinter.ttk import *
from PIL import Image, ImageTk

root = Tk()
root.title("Simple Image Viewer")
style = Style()


root.columnconfigure(0, weight=True)
root.rowconfigure(0, weight=True)

img1 = ImageTk.PhotoImage(Image.open("images/img_1.jpg"))
img2 = ImageTk.PhotoImage(Image.open("images/img_2.jpg"))
img3 = ImageTk.PhotoImage(Image.open("images/img_3.jpg"))

images = [img1, img2, img3]
img_idx = 0


def previous_image():
    global lbl_img
    global images
    global img_idx
    img_idx = img_idx - 1
    if img_idx < 0:
        img_idx = len(images) - 1
    try:
        lbl_img.configure(image=images[img_idx])
    except IndexError:
        img_idx = -1
        lbl_img.configure(image=images[img_idx])
    finally:
        status.configure(text=f"{img_idx + 1} of {len(images)} images.")


btn_back = Button(text="<", command=previous_image)


def forward_image():
    global lbl_img
    global images
    global img_idx
    img_idx = img_idx + 1
    try:
        lbl_img.configure(image=images[img_idx])
    except IndexError:
        img_idx = 0
        lbl_img.configure(image=images[img_idx])
    finally:
        status.configure(text=f"{img_idx + 1} of {len(images)} images.")


btn_forward = Button(text=">", command=forward_image)

lbl_img = Label(image=images[img_idx])

status = Label(root, text=f"{img_idx + 1} of {len(images)} images.", borderwidth=1,
               relief=SUNKEN, anchor="e")
status.grid(row=2, column=0, columnspan=3, stick=W+E)

btn_exit = Button(text="Exit", command=root.quit)
btn_back.grid(row=0, column=0, stick=W)
lbl_img.grid(row=0, column=1)
btn_forward.grid(row=0, column=2, stick=E)
btn_exit.grid(row=1, column=1)

root.mainloop()

When I run this then it comes like this: In small window

And when I maximize it: In maximize It comes like this. In above picture you can see that the image is not coming properly in center. My pictures must be in exact center in both in small and big window. Please can any one help me to do that by seeing my program.

Thanks in advance

Binamra
  • 164
  • 1
  • 9
  • 1
    You just need to change `root.columnconfigure(0, weight=True)` to `root.columnconfigure(1, weight=1)`. – acw1668 Aug 08 '20 at 12:39

3 Answers3

3

You can achieve this with grid you need to make sure that left and right get space, also up and down, but the middle gets no space. As an exampel:

import tkinter as tk

root = tk.Tk()

up = tk.Frame(root)
up.grid(column=0, row=0,columnspan=3,sticky='n')
s1 = tk.Label(up, text='spacer')
s1.pack()

left = tk.Frame(root)
b1 = tk.Button(left, text='B1')
left.grid(column=0,row=1,sticky='w')
b1.pack()

middle = tk.Frame(root)
middle.grid(column=1, row=1)
s2 = tk.Label(middle, text='spacer')
s2.pack()

down = tk.Frame(root)
qb = tk.Button(down, text='Exit', command= root.destroy)
down.grid(column=0, row=2,columnspan=3,sticky='s')
qb.pack()

right = tk.Frame(root)
right.grid(column=2,row=1,sticky='e')
b2 = tk.Button(right, text='B2')
b2.pack()

root.columnconfigure(0,weight=1) #left get space
root.columnconfigure(2,weight=1) #right get space

root.rowconfigure(0, weight=1) #up get space
root.rowconfigure(2, weight=1) #down get space

root.mainloop()

Ourput: enter image description here

For detail information what weight does.

Thingamabobs
  • 7,274
  • 5
  • 21
  • 54
2

I think there are 2 solutions you can do for this.

  1. When you are displaying your image onto the program you can do ....place(x=x_coord, y=y_coord, anchor=center) to make sure that the image is set and always is in the center of the program.

One tip is to set the resolution of the program at the very start and instead of using grids you can use coordinates and anchors which will place your buttons and images nicely (I think), I haven't tried it with images.

  1. Another solution which will probably fix your problem is determining if you want your program to be full screen. If you want your program to stay in a nice small window like on your first reference you can prevent the user from resizing the window. When you are maximizing the window you have not made the image to resize as the window gets bigger so I'm sure this is fine to do. At the start of your program after you define root... root.resizable(0, 0). This will prevent the user from resizing the window.
Dharman
  • 30,962
  • 25
  • 85
  • 135
  • 1
    No problem. If you don't intent for your program to be maximized then solution 2 will work fine, i'm pretty sure. – Kevin Apetrei Aug 08 '20 at 10:14
  • 1
    If you want the image to change when maximized try searching how to scale images in tkinter. I found a few links I think might help... https://pythonprogramming.altervista.org/tkinter-python-app-to-resize-images-part-1/ and https://www.codegrepper.com/code-examples/delphi/how+to+resize+image+in+python+tkinter – Kevin Apetrei Aug 08 '20 at 10:18
1

I implemented what you said but the buttons for me it is not perfect. I want to put the buttons on top of the label, I don't want them on the side.it is posible?

import tkinter as tk

    
root = tk.Tk()
image_list = getfiles()

up = tk.Frame(root)
up.grid(column=0, row=0,columnspan=3,sticky='n')
s1 = tk.Label(up, text='spacer')
s1.pack()

left = tk.Frame(root)
b1 = tk.Button(left, text='B1')
left.grid(column=0,row=1,sticky='w')
b1.pack()

middle = tk.Frame(root)
middle.grid(column=1, row=1)
s2 = tk.Label(middle, text='spacer')
image = Image.open(image_list[current])
photo = ImageTk.PhotoImage(image)
s2['image'] = photo
s2.photo = photo
s2.pack()

down = tk.Frame(root)
qb = tk.Button(down, text='Exit', command= root.destroy)
down.grid(column=0, row=2,columnspan=3,sticky='s')
qb.pack()

right = tk.Frame(root)
right.grid(column=2,row=1,sticky='e')
b2 = tk.Button(right, text='B2')
b2.pack()

root.columnconfigure(0,weight=1) #left get space
root.columnconfigure(2,weight=1) #right get space

root.rowconfigure(0, weight=1) #up get space
root.rowconfigure(2, weight=1) #down get space

root.mainloop()

To put the button in the same place than a Image you need place()

label = Tkinter.Label(root, compound=Tkinter.TOP)
label.pack()

A=Tkinter.Button(root, text='Previous picture', command=lambda: move(-1))
A.place(relx=0, x=2, y=20,width=130,height=100)
B=Tkinter.Button(root, text='Next picture', command=lambda: move(+1))
B.place(relx=0, x=135, y=20,width=130,height=100)
C=Tkinter.Button(root, text='PRINT', command=root.quit)
C.place(relx=1, x=-130, y=20,width=130,height=100)

move(0)
root.update()
root.mainloop()

virtualsets
  • 383
  • 2
  • 5
  • 17