pythonpython-3.xtkintertkinter-buttontkinter-photoimage

How can you make images fit within widget using PhotoImage (without use of PIL)?


I'm attempting to develop a solution with two buttons (without any libraries outside tkinter), one with a thumbs up image (like) and one with a thumbs down image (dislike), however I can't even seem to get the basics down of getting the images to fit within a button.

The python is as below:

from tkinter import *

window = Tk()
window.geometry("500x600")
window.title("Like and Dislike")

like_img = PhotoImage(file = "like.png")
dislike_img = PhotoImage(file = "dislike.png")

like_btn = Button(window, image = like_img)
like_btn.pack()

dislike_btn = Button(window, image = dislike_img)
dislike_btn.pack()

window.mainloop()

I've also tried to just put a logo inside of a label and I face the same issue.

logo_img = PhotoImage(file = "SurferBrosLogo.png")

logo_label = Label(window, image = logo_img)
logo_label.pack()

The images still seem to stick to the same dimensions of 1000+ x 1000+

I've attempted to change dimensions of the widgets which of course doesn't work as the issue is with the dimensions of the images. I attempted to just simply add height and width values to the PhotoImage() similar to what you'd do for HTML where I again had no success.

For my actual solution I would like to have it in a grid and fit within these dimensions of the widgets if at all possible:

from tkinter import *

window = Tk()
window.geometry("800x600")
window.title("Like and Dislike")

like_img = PhotoImage(file = "like.png")
dislike_img = PhotoImage(file = "dislike.png")

like_btn = Button(window, image = like_img, width = 50, height = 50).grid(column = 2, row = 0)

dislike_btn = Button(window, image = dislike_img, width = 50, height = 50).grid(column = 2, row = 1)

logo_img = PhotoImage(file ="Logo.png")

logo_label = Label(window, image = logo_img, width = 400, height = 500).grid(column=1, row = 0)
below_label = Label(window, text = "Liking and Disliking", font = "Arial").grid(column = 1, row = 1)

window.mainloop()

For reference, the image on the left is supposed to be a logo with the name of the company underneath and the buttons should be off to the right, however at the moment they are heavily separated.

Any help would be greatly appreciated!


Solution

  • You have to resize both the buttons and the images. Tkinter offers the rather limited subsample() method for PhotoImage objects for which you have to calculate the correct resizing factors, based on the images' actual and desired width and height. This is controlled through the TARGET_SIZE constant:

    from tkinter import Tk, PhotoImage, Button
    
    window = Tk()
    window.geometry("500x600")
    window.title("Like and Dislike")
    
    TARGET_SIZE = 30
    like_img = PhotoImage(file="like.png")
    like_x_factor = like_img.width() // TARGET_SIZE
    like_y_factor = like_img.height() // TARGET_SIZE
    like_img_resized = like_img.subsample(like_x_factor, like_y_factor)
    
    dislike_img = PhotoImage(file="dislike.png")
    dislike_x_factor = dislike_img.width() // TARGET_SIZE
    dislike_y_factor = dislike_img.height() // TARGET_SIZE
    dislike_img_resized = dislike_img.subsample(dislike_x_factor, dislike_y_factor)
    
    like_btn = Button(window, image=like_img_resized, width=TARGET_SIZE, height=TARGET_SIZE)
    like_btn.pack()
    
    dislike_btn = Button(window, image=dislike_img_resized, width=TARGET_SIZE, height=TARGET_SIZE)
    dislike_btn.pack()
    
    window.mainloop()