[Tkinter] Locking Canvas to a Window - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: GUI (https://python-forum.io/forum-10.html) +--- Thread: [Tkinter] Locking Canvas to a Window (/thread-27390.html) |
Locking Canvas to a Window - drnshaw - Jun-05-2020 I've searched and experimented but am unable to solve my problem with canvas. I have been teaching myself Python. I first wrote a text program to test my knowledge of lists, dictionaries, etc. The program runs well. It's not a useful program but does provide me practice in doing various things. I then spent time converting it to a GUI. The GUI version works well (from my perspective); however, one issue, a minor one but it's bugging me, still exists. I create my window and then I create a canvas. Inside the canvas, place an image. That all works fine. The problem comes when I call a method from a class - the method works just fine but the image disappears. I actually have two classes - the super class that performs actions relative to adding, editing, deleting records, and a method (here) displaying the dictionary records and a subclass that performs the menubar. Here's some of the code: class People: # abbreviated class; only showing two methods def __init(self): self.frame = Frame(window def view_records(self): self.frame.destroy() self.frame = Frame(window) self.frame.configure(bg='light green') self.frame.grid(row=0, column=0) """ I tried recreating the canvas and that didn't work. """ # canvas = Canvas(window, bg='light green', width=245, height=245) # image = ImageTk.PhotoImage(Image.open("picture.png")) # open the Army file # canvas.create_image(0, 0, anchor=NW, image=image) # draw the image current_row = 10 for key in self.people: person = 'Record: ' + str(key) + str(self.people[key]) label = Label(self.frame, text=person, bg='light green', font=('Helvetica', 8, 'bold')) label.grid(row=current_row, column=2, sticky=W) current_row += 1 window = Tk() window.title("People System") window.geometry("750x300+325+200") window.configure(bg='light green') canvas = Canvas(window, bg='light green', width=245, height=245) image = ImageTk.PhotoImage(Image.open("picture.png")) # open the Army file canvas.create_image(0, 0, anchor=NW, image=image) # draw the image """ padx and pady do put the window on the far right if I adjust 'padx'; however, if I run 'view_records', the image disappears. """ canvas.grid(row=0, column=3, padx=500, pady=0, sticky=W) people = CreateMenu() people.view_records() window.mainloop()Any help would be greatly appreciated. Thanks, Nick. RE: Locking Canvas to a Window - deanhystad - Jun-05-2020 The image is being garbage collected because the only reference to image is destroyed as soon as the code returns from view_records.. Try using a global variable or an instance variable instead of the local variable "image" in method "view_records". RE: Locking Canvas to a Window - drnshaw - Jun-05-2020 I don't think I was really clear about what I'm trying to achieve. I'm trying to put the image on the far right of the window and when I run any of the methods, it doesn't move and the image is always visible. If I put the image at x=0, y=0, it all works; however, as each method is called (add_record, edit_record, delete_record, or show_records), the image moves around the window. In advance, thank you! Nick. Thank you, deanhystad, I'll try that. What, in my code, is destroying the image? Nick. RE: Locking Canvas to a Window - deanhystad - Jun-05-2020 All objects in python have a reference count. When the reference count goes to zero, the memory used by the object is reclaimed. This is called garbage collection. The image you create in method "view_records" is only referenced by the local variable "image". When the method is done, the local variables are deleted and nobody is referencing the image you just created. RE: Locking Canvas to a Window - drnshaw - Jun-06-2020 Is this what you are referring to? No change. I'm obviously missing something; doing some research on 'garbage collection in Python'. def view_records(self): """ Display all records in the dictionary, one record per line. """ self.frame.destroy() # clear the window canvas self.frame = Frame(window) # create a new window canvas self.frame.configure(bg='light green') self.frame.grid(row=0, column=0) global canvas canvas = Canvas(window, bg='light green', width=245, height=245) global image image = ImageTk.PhotoImage(Image.open("picture.png")) canvas.create_image(0, 0, anchor=NW, image=image) current_row = 10 for key in self.people: person = 'Record: ' + str(key) + str(self.people[key]) label = Label(self.frame, text=person, bg='light green', font=('Helvetica', 8, 'bold')) label.grid(row=current_row, column=2, sticky=W) current_row += 1 # use the next row for the next record |