PIL/tkinter - updating label image with button images

Post here if you need help with creating a Graphical User Interface in Python.

PIL/tkinter - updating label image with button images

Postby Chilcone » Mon Jan 13, 2014 8:51 pm

Hey all,
I'm trying to implement my simple image viewer, where I have one main label and menubutton with three choices. Each of them creates different numbers of buttons with pictures inside them. I would like create one main label and then update its image with images on the buttons. So when I click on the first button with image, that image will appear on the label, then click second button and that second image will appear and so on. I've tried to create two functions one for creating label and updating its image and the second for getting current image on the button, but I wasn't able to do the second one correctly.
Appreciate your help. Here's the code:

Code: Select all
try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk

from functools import partial
from PIL import Image, ImageTk

class Halabala():
    def __init__(self):
        self.master = tk.Tk()
        self.master.geometry("1100x700")
        self.pictures = ["pavuk1.gif", "pavuk2.gif", "pavuk3.gif"]
        self.pictures2 = ["cukor1.gif", "cukor2.gif", "cukor3.gif", "cukor4.gif", "cukor5.gif"]

        self.lists_images = []
        self.lists_images2 = []

        self.init_image_list()

        self.lists_labels = []

        #self.main_label = tk.Label(self.master, image = None).grid(row = 0, column = 0)
        #image with original size

        self.rbutton = tk.Menubutton(self.master, text = "Choose picture")
        self.picks2 = tk.Menu(self.rbutton)
        self.rbutton.config(menu=self.picks2)
        self.picks2.add_command(label = "Spider", command = partial(self.create_labels,3))
        self.picks2.add_command(label = "Sugar", command = partial(self.create_labels,5))
        self.rbutton.config(width = 30, bg = "white", bd = 5, relief = tk.RAISED)
        self.rbutton.place(x = 900, y = 30)
        self.master.mainloop()

    def init_image_list(self):
        for i in self.pictures:
                picture = Image.open(i)
                picture.thumbnail((130, 130))
                self.lists_images.append(ImageTk.PhotoImage(picture))

        for i in self.pictures2:
                picture = Image.open(i)
                picture.thumbnail((130, 130))
                self.lists_images2.append(ImageTk.PhotoImage(picture))


    def create_labels(self, num):

        for label in self.lists_labels:
            label.destroy()
        self.lists_labels=[]

        for i in range(num):
            if num == 3:
                but = tk.Button(self.master, image = self.lists_images[i]) #command = self.get_command
                but.grid(row = 2, column = i + 1) #label will be in the first row
                self.lists_labels.append(but)
            else:
                but = tk.Button(self.master, image = self.lists_images2[i])
                but.grid(row = 2, column = i + 1)
                self.lists_labels.append(but)

    #def get_command(self):
        #self.main_label = tk.Label(self.master, image = self.get_image).grid(row = 0, column = 0)

    #def get_image(self):
    # don't know how to get current image from button

myapp = Halabala()
Chilcone
 
Posts: 6
Joined: Sun Jan 05, 2014 12:33 pm

Re: PIL/tkinter - updating label image with button images

Postby wuf » Wed Jan 15, 2014 5:32 pm

Hi Chilcone

Always need words which make sense in your script. Someone can style a script in many ways. Here i have used my own style. Try out the following script:
Code: Select all
#!/usr/bin/env python
# coding: UTF-8

from functools import partial
from PIL import Image, ImageTk

try:
    #~~ For Python 2.x
    import Tkinter as tk
except ImportError:
    #~~ For Python 3.x
    import tkinter as tk

APP_WIN_XPOS = 0
APP_WIN_YPOS = 0
APP_WIN_WIDTH = 1100
APP_WIN_HEIGHT = 700

MENU_ITEMS = ["Spider", "Sugar"]
IMAGES = {
    "Spider": ["pavuk1.gif", "pavuk2.gif", "pavuk3.gif"],
    "Sugar" : ["cukor1.gif", "cukor2.gif", "cukor3.gif", "cukor4.gif",
               "cukor5.gif"],
    }


class App(object):
   
    def __init__(self, title):
        self.win = tk.Tk()
        self.win.title(title)
        self.win.geometry('{0}x{1}+{2}+{3}'.format(APP_WIN_WIDTH,
            APP_WIN_HEIGHT, APP_WIN_XPOS, APP_WIN_YPOS))
        self.win.protocol("WM_DELETE_WINDOW", self.close)

        self.menu_button = tk.Menubutton(self.win,
            text="Choose picture")
        self.menu = tk.Menu(self.menu_button)
       
        for menu_item in MENU_ITEMS:
            self.menu.add_command(label=menu_item,
            command=partial(self.create_buttons, menu_item))
           
        self.menu_button.config(menu=self.menu, width=30, bg="white",
            bd=5, relief='raised')
        self.menu_button.place(x=800, y=30)
               
        self.tk_images = dict()
        self.image_display_label = None
       
        self.create_tk_images()

    def create_tk_images(self):
        for menu_item in MENU_ITEMS:
            self.tk_images[menu_item] = list()
            image_names = IMAGES[menu_item]
            for image_name in image_names:
                image = Image.open(image_name)
                image.thumbnail((130, 130))
                self.tk_images[menu_item].append(
                    ImageTk.PhotoImage(image))
       
    def create_buttons(self, menu_item):
        if self.image_display_label != None:
            self.image_display_label.destroy()
            self.image_display_label = None
           
        tk_images = self.tk_images[menu_item]
        for index, tk_image in enumerate(tk_images):
            tk.Button(self.win, image=tk_image,
                command=partial(
                    self.get_image, menu_item, index)).grid(
                row=1, column=index)
   
    def get_image(self, menu_item, index):
        if self.image_display_label == None:
            self.image_display_label = tk.Label(self.win)
            self.image_display_label.grid(row = 0, column = 0)

        tk_image = self.tk_images[menu_item][index]
        self.image_display_label.configure(image=tk_image)
           
    def run(self):
        self.win.mainloop()
   
    def close(self):
        print("Do something before shutdown")
        self.win.destroy()
           
app = App("Tk App Templates").run()

wuf ;)
wuf
 
Posts: 37
Joined: Fri Feb 08, 2013 6:42 am

Re: PIL/tkinter - updating label image with button images

Postby Chilcone » Thu Jan 16, 2014 5:09 pm

Thank you very much :)
Chilcone
 
Posts: 6
Joined: Sun Jan 05, 2014 12:33 pm

Re: PIL/tkinter - updating label image with button images

Postby Chilcone » Fri Jan 17, 2014 11:35 pm

Actually, your code has one problem, because after choosing second image (Sugar) and then the first one(Spider), the two additional buttons from sugar picture stay on the screen.
Chilcone
 
Posts: 6
Joined: Sun Jan 05, 2014 12:33 pm

Re: PIL/tkinter - updating label image with button images

Postby wuf » Sat Jan 18, 2014 10:00 am

Hi Chilcone

You are right. In my code script is missing something, which i have complemented now. Hope it works well for you:
Code: Select all
#!/usr/bin/env python
# coding: UTF-8

from functools import partial
from PIL import Image, ImageTk

try:
    #~~ For Python 2.x
    import Tkinter as tk
except ImportError:
    #~~ For Python 3.x
    import tkinter as tk

APP_WIN_XPOS = 0
APP_WIN_YPOS = 0
APP_WIN_WIDTH = 1100
APP_WIN_HEIGHT = 700

MENU_ITEMS = ["Spider", "Sugar"]
IMAGES = {
    "Spider": ["5.gif", "6.gif", "7.gif"],
    "Sugar" : ["0.gif", "1.gif", "2.gif", "3.gif", "4.gif"],
    }
   
class App(object):
   
    def __init__(self, title):
        self.win = tk.Tk()
        self.win.title(title)
        self.win.geometry('{0}x{1}+{2}+{3}'.format(APP_WIN_WIDTH,
            APP_WIN_HEIGHT, APP_WIN_XPOS, APP_WIN_YPOS))
        self.win.protocol("WM_DELETE_WINDOW", self.close)

        self.menu_button = tk.Menubutton(self.win,
            text="Choose picture")
        self.menu = tk.Menu(self.menu_button)
       
        for menu_item in MENU_ITEMS:
            self.menu.add_command(label=menu_item,
            command=partial(self.create_buttons, menu_item))
           
        self.menu_button.config(menu=self.menu, width=30, bg="white",
            bd=5, relief='raised')
        self.menu_button.place(x=800, y=30)
               
        self.tk_images = dict()
        self.buttons = list()
        self.image_display_label = None
       
        self.create_tk_images()

    def create_tk_images(self):
        for menu_item in MENU_ITEMS:
            self.tk_images[menu_item] = list()
            image_names = IMAGES[menu_item]
            for image_name in image_names:
                image = Image.open(image_name)
                image.thumbnail((130, 130))
                self.tk_images[menu_item].append(
                    ImageTk.PhotoImage(image))
       
    def create_buttons(self, menu_item):
       
        # Remove a selected image
        if self.image_display_label != None:
            self.image_display_label.destroy()
            self.image_display_label = None
       
        # Remove existing buttons   
        if self.buttons != []:
            for button in self.buttons:
                button.destroy()
                   
        tk_images = self.tk_images[menu_item]
        for index, tk_image in enumerate(tk_images):
            button = tk.Button(self.win, image=tk_image,
                command=partial(self.get_image, menu_item, index))
            button.grid(row=1, column=index)
            self.buttons.append(button)
           
    def get_image(self, menu_item, index):
        if self.image_display_label == None:
            self.image_display_label = tk.Label(self.win)
            self.image_display_label.grid(row = 0, column = 0)

        tk_image = self.tk_images[menu_item][index]
        self.image_display_label.configure(image=tk_image)
           
    def run(self):
        self.win.mainloop()
   
    def close(self):
        print("Do something before shutdown")
        self.win.destroy()
           
app = App("Tk App Templates").run()

wuf ;)
wuf
 
Posts: 37
Joined: Fri Feb 08, 2013 6:42 am

Re: PIL/tkinter - updating label image with button images

Postby Chilcone » Sat Jan 18, 2014 3:29 pm

Hi again !
I have my last question :) I would like to show label instantly after I choose picture from menubutton. So when I click, e.g on spider, the label will show the first image of the currently selected picture and not after I click on the buttons.
Really thanks for all your help :)
Chilcone
 
Posts: 6
Joined: Sun Jan 05, 2014 12:33 pm

Re: PIL/tkinter - updating label image with button images

Postby wuf » Sat Jan 18, 2014 4:43 pm

Hi Chilcone

No problem. The following modification should do the job:
Code: Select all
    def create_buttons(self, menu_item):
       
        # Remove existing buttons   
        if self.buttons != []:
            for button in self.buttons:
                button.destroy()
                   
        tk_images = self.tk_images[menu_item]
        for index, tk_image in enumerate(tk_images):
            button = tk.Button(self.win, image=tk_image,
                command=partial(self.get_image, menu_item, index))
            button.grid(row=1, column=index)
            self.buttons.append(button)
       
        # Display the image of the 1st Button of the sequence
        self.get_image(menu_item, 0)

wuf ;)
wuf
 
Posts: 37
Joined: Fri Feb 08, 2013 6:42 am


Return to GUI

Who is online

Users browsing this forum: No registered users and 6 guests