Reputation: 19005
I am just getting started with tkinter
widgets and am trying to create Checkbuttons
with both images and text labels. Unfortunately, this cannot be done with basic Checkbutton(master=, image=, text=)
as setting the image
suppresses the text
.
Here's a silly yet reproducible example of what I'm trying to do.
from tkinter import Tk, Frame, Checkbutton, Label
from PIL import ImageTk, Image
import requests
def getImgFromUrl(url): # using solution from : https://stackoverflow.com/a/18369957/2573061
try:
r = requests.get(url, stream=True)
pilImage = Image.open(r.raw)
phoImage = ImageTk.PhotoImage(pilImage)
return phoImage
except Exception as e:
print('Error ' + repr(e) )
return None
class AnimalPicker(Frame):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.master.title("Animal Picker")
def main():
root = Tk()
root.geometry("250x450+300+300")
app = AnimalPicker()
imageUrls = ['http://icons.iconarchive.com/icons/martin-berube/flat-animal/64/dachshund-icon.png',
'http://icons.iconarchive.com/icons/iconka/meow/64/cat-walk-icon.png',
'http://icons.iconarchive.com/icons/sonya/swarm/64/Unicorn-icon.png']
labels = ['Dog','Cat','Unicorn']
images = [getImgFromUrl(x) for x in imageUrls]
for i in range(len(images)):
cb = Checkbutton(root, text=labels[i], image = images[i])
cb.pack(anchor = 'w', padx=5,pady=5)
root.mainloop()
if __name__ == '__main__':
main()
Gives me:
But I would like to have the labels "Cat", "Dog", and "Unicorn" either underneath or to the side of the images.
It's also important that the solution work for an arbitrary number of Checkbuttons
, as in the for
loop above.
Should I be using Grid and stacking these Checkbuttons
next to Labels
? I've managed to avoid learning it so far. Or is it easy to do with Pack
?
Upvotes: 4
Views: 2982
Reputation: 15335
I would like to have the labels ("Cat", "Dog", "Unicorn") either underneath or to the side of the images.
As suggested in Bryan's comment, this can be done by configuring compound
option of Checkbutton
.
Simply replace:
cb = Checkbutton(root, text=labels[i], image = images[i])
with:
cb = Checkbutton(root, text=labels[i], image = images[i], compound='left')
or set compound
option to an element of ['bottom', 'center', 'left', 'right', 'top']
which is by default None
:
cb['compound'] = 'top'
Below example produces an example for most Windows users:
import tkinter as tk
from PIL import Image, ImageTk
root = tk.Tk()
mypath = r"C:\Users\Public\Pictures\Sample Pictures\Koala.jpg"
img = Image.open(mypath)
glb_img = ImageTk.PhotoImage(img)
tk.Checkbutton(root, text="Koala", image=glb_img, compound='top').pack()
root.mainloop()
Also it's worth noting that importing PIL
is redundant for .png
format, one could use either tk.PhotoImage(data=image_data)
or tk.PhotoImage(file=image_file)
.
Upvotes: 5