#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2015
    Posts
    3
    Rep Power
    0

    A newbie Tkinter question...


    My son is finishing up a Python Class Project “Movie Ticket Kiosk” and has run into a wall.
    He went over the top with the project instead of simply text driven menus he went full GFX using tkinter.
    While I applaud this, due date is fast approaching and he stubbornly is hitting his head against the wall refusing help.

    My programming knowledge has long evaporated so I scoured the net looking for his description of the problem.

    I think it’s a newbie problem.

    Basically he has a tkinter screen setup with many frames.
    The frames are setup for movie screens/ ticket type/ food combo/ etc depending on the stage of the users inputs.
    He explained to me that the images can’t simply be drawn overtop and need to be deleted first (using (forget) command?)
    Anyways, he has it flipping images no problem but ¾ into the program he is now getting errors that work fine in other parts of his code. Apparently he is losing reference to images etc. because he is outside of the functions?

    I am sorry I can’t explain better but in searching noticed some remarks in code labels:
    “A src attribute is added to avoid Python's garbage collection routines losing the references to the images”

    I think this is a variable outside of a function not being seen?

    Thank you ahead of time.

    Signed… Old Programming Dad now just an Old fisherman…
  2. #2
  3. Contributing User
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Aug 2011
    Posts
    5,838
    Rep Power
    509
    Nice sleuthing work. Based on the no code you've shown but having seen this bit of the documentation before today, yes, the program needs to keep a separate reference to the (image or whatever you identified).

    It's easy to do---just assign that value to a separate variable as well as what gets passed off to tkinter. Just make sure the variable stays in scope, so it could be a global variable (a global list of images would be a reasonable solution) or if it's an object oriented design the code could assign that reference to a a variable in the object and of course it would need to be a persistent object.
    Code:
            self.ExtraReference = img
    ...
        global keepMe
        keepMe = reference
    ...
    
    RetainedReferences = list()
    ########
        RetainedReferences.append(yet_another_image)
            #the assignment might look like these
            #
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2015
    Posts
    3
    Rep Power
    0
    Originally Posted by b49P23TIvg
    Nice sleuthing work. Based on the no code you've shown but having seen this bit of the documentation before today, yes, the program needs to keep a separate reference to the (image or whatever you identified).

    It's easy to do---just assign that value to a separate variable as well as what gets passed off to tkinter. Just make sure the variable stays in scope, so it could be a global variable (a global list of images would be a reasonable solution) or if it's an object oriented design the code could assign that reference to a a variable in the object and of course it would need to be a persistent object.
    Code:
            self.ExtraReference = img
    ...
        global keepMe
        keepMe = reference
    ...
    
    RetainedReferences = list()
    ########
        RetainedReferences.append(yet_another_image)
            #the assignment might look like these
            #

    Thank you very much for the quick reply.
    I did not include code because I thought it was more of a "concept" answer like yours above than a syntax error.

    here is some I clip out thats not working

    **********************

    # I want to delete the label's named with time(1-4) but they aren't defined in this function
    label_child = Label(OF1_IF1_T, width=200, height=250, image=child_Ticket)
    label_child.pack()
    label2.pack_forget()
    label_student = Label(OF1_IF2_T, width=200, height=250, image=student_Ticket)
    label_student.pack()
    label3.pack_forget()
    label_general = Label(OF1_IF3_T, width=200, height=250, image=general_Ticket)
    label_general.pack()
    label4.pack_forget()
    label_senior = Label(OF1_IF4_T, width=200, height=250, image=senior_Ticket)
    label_senior.pack()


    ********************************************************

    Again, thank you for the reply as it probably will be the HINT thats needed!
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    May 2009
    Posts
    652
    Rep Power
    39
    I would strongly suggest that you learn classes before Tkinter. Classes take care of things like
    I want to delete the label's named with time(1-4) but they aren't defined in this function
    One tutorial = Think Python
    More at https://wiki.python.org/moin/Beginne...NonProgrammers

    A simple example for displaying images and changing them.
    Code:
    try:
        import Tkinter as tk     ## Python 2.x
    except ImportError:
        import tkinter as tk     ## Python 3.x
    
    class ImageTest():
        def __init__(self):
            self.root = tk.Tk()
    
            self.root.title('image test')
            self.image_list= []
            self.load_images()
            self.panel1 = tk.Label(self.root, image=self.image_list[0])
            self.panel1.grid()
            self.first_image=True
    
            tk.Button(self.root, text="Next Pic", command=self.callback,
                      bg="lightblue").grid(row=1)
            tk.Button(self.root, text="Exit", command=quit,
                      bg="red").grid(row=2, sticky="nsew")
    
            self.root.mainloop()
    
        def callback(self):
            if self.first_image:
                self.panel1["image"]=self.image_list[1]
            else:
                self.panel1.config(image=self.image_list[0])
            self.first_image=not self.first_image
    
        def load_images(self):
            """ use inline images for testing
                note that photo uses "data" instead of "file" for these
            """
            grape_gif_b64='''\
    R0lGODlhIAAgALMAAAAAAAAAgHCAkC6LV76+vvXeswD/ANzc3DLNMubm+v/6zS9PT6Ai8P8A////
    /////yH5BAEAAAkALAAAAAAgACAAAAS00MlJq7046803AF3ofAYYfh8GIEvpoUZcmtOKAO5rLMva
    0rYVKqX5IEq3XDAZo1GGiOhw5rtJc09cVGo7orYwYtYo3d4+DBxJWuSCAQ30+vNTGcxnOIARj3eT
    YhJDQ3woDGl7foNiKBV7aYeEkHEignKFkk4ciYaImJqbkZ+PjZUjaJOElKanqJyRrJyZgSKkokOs
    NYa2q7mcirC5I5FofsK6hcHHgsSgx4a9yzXK0rrV19gRADs=
    '''
            ladybug_gif_b64='''\
    R0lGODlhIAAgALMAAP///wAAADAwMP99Hf8AAP+lAP//AMopUwAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAACH5BAAAAAAALAAAAAAgACAAAwTHEMhJq714hp3lDh0GiqH2UWOVAt96pUIsBLKglWg87Dwv
    4xMBj0Asxgg+XKxwLBJrxUGsI5TKnARoVHoLDp5XbNP5cwmNAqwa/aOc13ByrfKOw2UGw1SSxrb+
    AWIxeXsAaX92UDQ1Nh6BdneMhQIHkHGSjYaVlmt4epmacp19YAKEoJRspKWrjBapWWGqcm1uB5tj
    ok4HZa+3m5wEt5kuhpTAcb+FVL/NzspAfDHPysslMJjEIS0oLygnOMVd0SwcHeDk6errEQA7
    '''
    
            ## store image in instance variable,
            ## otherwise it is garbage collected when function exits
            photo=tk.PhotoImage(data=grape_gif_b64)
            self.image_list.append(photo)
            photo=tk.PhotoImage(data=ladybug_gif_b64)
            self.image_list.append(photo)
    
    IT=ImageTest()
    FYI for future posts, no one has any idea what either of these statements mean
    thats not working

    # I want to delete the label's named with time(1-4) but they aren't defined in this function

    Comments on this post

    • b49P23TIvg agrees : Excellent example!
    Last edited by dwblas; February 11th, 2015 at 12:49 PM.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2015
    Posts
    3
    Rep Power
    0
    Thanks a ton for the reply.

    My son will be going over this for sure.

    His course is basically self learn and he has 3 weeks per language project (Java/python/c#/ruby etc.) so he tries to put out a sharp looking result (lots of eye candy - NO text driven menus) for top marks.

    This of course leads to a lot of basic concepts skipped over with brute force redundant program structure but maybe that's teaching how to meet a real life deadline... He also has a few other high end Grade 12 courses going on at the same time so that's why I go looking for hints to help him out.

    Again, thank you for the time taken with these great examples, much appreciated.
  10. #6
  11. Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Feb 2005
    Posts
    635
    Rep Power
    68
    Another example ...
    Code:
    ''' tk_image_persist1.py
    create Tkinter image objects and display them ...
    create all image objects in __main__ to be persistent
    Note: if you create the image object and tie it to a
    function scope variable, then when the function is done
    the image will be garbage collected
    '''
    
    try:
        # Python2
        import Tkinter as tk
    except ImportError:
        # Python3
        import tkinter as tk
    
    def toggle_image(event):
        """toggle betwen two images"""
        print(label['image'], type(label['image']))  # test
        if label['image'] == 'pyimage2':
            label['image'] = image1
        else:
            label['image'] = image2
    
    # code below is considered __main__
    root = tk.Tk()
    root.title("Click on the image to change it")
    
    # pick images you have in the working directory
    # or give full path
    image1 = tk.PhotoImage(file='Farm.gif')
    image2 = tk.PhotoImage(file='Pond.gif')
    
    # create a label to display the image
    label = tk.Label(root, image=image1, relief='raised', bd=10)
    label.grid(row=1, column=1)
    # bind left mouse click
    label.bind('<Button-1>', toggle_image)  
    
    root.mainloop()
    Real Programmers always confuse Christmas and Halloween because Oct31 == Dec25
  12. #7
  13. Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Feb 2005
    Posts
    635
    Rep Power
    68
    Another option ...
    Code:
    label_child = Label(OF1_IF1_T, width=200, height=250, image=child_Ticket)
    label_child.image = child_Ticket
    ... and so on
    Real Programmers always confuse Christmas and Halloween because Oct31 == Dec25

IMN logo majestic logo threadwatch logo seochat tools logo