-1

I've tried to make a customized container function for my application, but when I pass the list of widgets, they does not get visible. The container is like the LabelFrame but with rounded corners. I tried a lot of things, but nothing seems to work. Please let me know what I'm doing wrong.

Here is my code and some comments for it:

parent -> this is the top level window

lbl_text -> this will be the little text like the LabelFrame has on top

widgets -> this is the list of the widgets I would like to place in my rounded frame

def rndframe(parent, lbl_text, widgets
    # content_positioner and max_width is for calculate the requiered size of the canvas to be big 
    # enough for all the passed widgets, and to determine the coordinates for create_window function. 
    # It works perfectly and I get all the information I want.
    content_positioner = [14]
    max_width = 1
    for i, item in enumerate(widgets):
        content_positioner.append(content_positioner[i]+widgets[i].winfo_reqheight())
        if widgets[i].winfo_reqwidth() > max_width:
            max_width = widgets[i].winfo_reqwidth()

    height = max(content_positioner)+10
    width = max_width+10

    # Here I create the canvas which will contain everything
    canv = TK.Canvas(parent, height=height, width=width, bg='green', bd=0, highlightthickness=0)
    
    # Here I draw the rounded frame
    radius = 10
    x1 = 2
    y1 = 5
    x2 = width-2
    y2 = height-2
    points = [x1+radius, y1, x2-radius, y1, x2, y1, x2, y1+radius, x2, y2-radius, x2, y2,               
              x2-radius, y2, x1+radius, y2, x1, y2, x1, y2-radius, x1, y1+radius, x1, y1]             
    canv.create_polygon(points, smooth=True, outline=DS.menu_bg, width=3, fill='')

    # Here I put the litle label in the frmae 
    label = TK.Label(parent, text=lbl_text, bg=DS.main_bg, padx=3, pady=0, fg=DS.main_textcolor)
    canv.create_window(18, 5, anchor='w', window=label)

    # And thats the part where I would like to place all the passed widgets based on the coordinate 
    # list I preveously created but nothing appear just the frame polygon and the liitle label on it.
    for w, widget in enumerate(widgets):
        canv.create_window(width/2, content_positioner[w], anchor='n', window=widgets[w])

    return canv

And finally the way I've tried to use:

id_num = TK.Label(result_area_leaf, text='123-4567')
id_num2 = TK.Label(result_area_leaf, text='123-4567')
id_holder = rndframe(result_area_leaf, lbl_text='id', widgets=[id_num, id_num2])
id_holder.grid()
acw1668
  • 40,144
  • 5
  • 22
  • 34

2 Answers2

1

There are many problems with your code, but the root of the issue is that the widgets you're adding to the canvas have a lower stacking order than the canvas so they are behind or "under" the canvas. This is because the default stacking order is initially determined by the order that the widgets are created. You create the widgets before the canvas so they are lower in the stacking order.

The simplest solution to the stacking order problem is to raise the widgets above the canvas, which you can do with the lift method.

for w, widget in enumerate(widgets):
    canv.create_window(width/2, content_positioner[w], anchor='n', window=widgets[w])
    widgets[w].lift()

When I make the above modification, along with fixing all of the other problems in the code, the labels appear in the canvas.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • You half way right and half way wrong :), but give me an idea that finaly worked. – Sometimes I Feel Like... Zipi Oct 09 '20 at 16:41
  • @SometimesIFeelLike...Zipi: I'm sorry. You're correct, I was wrong about you not calling `grid`. I updated my answer. I think it's now fully correct. – Bryan Oakley Oct 09 '20 at 16:45
  • Yes it' correct now but I don't understand why it needed to call '.lift()' to make it work in the stand alone code and why doesn't in the place my full application. The answer lays in somewhere in what you write about the stacking order but i can't figure it out :) – Sometimes I Feel Like... Zipi Oct 09 '20 at 17:02
0

Finally I got it work. First of all sorry that I didn't posted a standalone runable code firstly. When I put the code in a file and make the necessary changes about the missing variables the suggested .lift() method worked. And the reason was that in that single file I used the root window as parent.

In my copied code the two Lables (id_num and id_num2) have a Canvas for parent (result_area_leaf) and that was the problem. If I made my root window as parent for the passed widgets, the widgets are shown. The .lift() actually does not needed after all.

Thanks guys ;)