Rastko Gojgic
Rastko Gojgic

Reputation: 53

How to display widgets on a frame that is mounted on canvas in Tkinter?

I created a main root with two frames.

-One frame is for program toolbar.

-Other frame is for canvas where data will be displayed and a scrollbar widget.

-Inside of the canvas is a third smaller frame which will be used for scrolling trough data.

However, when I try to define new widgets and place them on that third smaller frame, nothing happens. I'm defining new widgets inside of a function call of a button command. I have also tried declaring everything as global variables but without luck.

Hint: I tried placing the code from the function to the top level of the code and it works. Also, if I try to mount these widgets on the toolbar frame it also works. It seems that the only thing I can't do is to mount these new widgets on the small frame that is inside the canvas.

I used a simple for loop to create labels just for testing.

Could anyone tell what I am doing wrong?

from tkinter import *
from tkinter import ttk



#Creating main window
root = Tk()
root.resizable(width=False, height=False)



#Defining Background

toolbar = Frame(root, width=613, height=114)
toolbar.grid(row=0, column=0)

background_frame = Frame(root, width=615, height=560)
background_frame.grid(row=1, column=0)

background = Canvas(background_frame, width=615, height=560)
background.pack(side=LEFT, fill=BOTH, expand=1)

scroll_bar = ttk.Scrollbar(background_frame, orient=VERTICAL, command=background.yview)
scroll_bar.pack(side=RIGHT, fill=Y)

background.configure(yscrollcommand=scroll_bar.set)
background.bind('<Configure>', lambda e:background.configure(scrollregion = background.bbox('all')))

second_frame = Frame(background)
background.create_window(150,100, window=second_frame, anchor='nw')


def confirm1():
    
    
    for x in range(100): 
        Label(second_frame, text = x ).grid(row=x, column=1)




show_labels = Button(toolbar, text= "Show labels", fg="black", command=confirm1)
show_labels.grid(row=0, column=2)

root.mainloop()

Picture of the app so far

Upvotes: 1

Views: 376

Answers (1)

Art
Art

Reputation: 3089

I surely can't reproduce the issue with your current code, but looking at the previous edit it is pretty clear what your problem is.

(taken from your previous edit)

def confirm1():
    
    global background_image1

    background.delete('all')  # <--- this line of code
 
    for x in range(100): 
        Label(second_frame, text = x ).grid(row=x, column=1)

Here you delete all your items from your canvas:

background.delete('all') 

hence no item appears.

You should instead delete only those items that you want to remove by passing the id or tags to delete method. You can delete multiple items together at once by giving the same tags.

Another option would be to recreate the frame item again on canvas using create_window (Do note: your frame is not deleted/destroyed, it's only removed from canvas)

Upvotes: 1

Related Questions