【问题标题】:Tkinter Canvas create_window function does not show the desired widgetsTkinter Canvas create_window 函数未显示所需的小部件
【发布时间】:2020-10-09 07:17:47
【问题描述】:

我尝试为我的应用程序创建自定义容器函数,但是当我传递小部件列表时,它们不可见。该容器类似于LabelFrame,但带有圆角。我尝试了很多东西,但似乎没有任何效果。请让我知道我做错了什么。

这是我的代码和它的一些 cmets:

parent -> 这是顶层窗口

lbl_text -> 这将是像LabelFrame 顶部的小文本

widgets -> 这是我想放在圆形框架中的小部件列表

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

最后是我尝试使用的方式:

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()

【问题讨论】:

  • 可能位置不对。尝试在 0、0 处绘制小部件进行测试。
  • 我已经测试过在画布之前创建的小部件不会使用create_window() 显示。太奇怪了。
  • @Wups 我已经尝试过了,清除了所有内容,只是要求函数在 0;0 处创建传递的小部件,但没有奏效。
  • @acw1668:谢谢。我的想法是将此函数转换为一个类并创建一个用于放置小部件的函数(这样可以在画布之后创建小部件并且我可以调整它的大小)。

标签: python tkinter canvas


【解决方案1】:

您的代码存在许多问题,但问题的根源在于您添加到画布的小部件的堆叠顺序低于画布,因此它们位于画布的后面或“下方”。这是因为默认的堆叠顺序最初是由创建小部件的顺序决定的。您在画布之前创建小部件,因此它们在堆叠顺序中较低。

堆叠顺序问题的最简单解决方案是将小部件提升到画布上方,您可以使用lift 方法来做到这一点。

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

当我进行上述修改并修复代码中的所有其他问题时,标签会出现在画布中。

【讨论】:

  • 你一半对一半错:),但给我一个最终奏效的想法。
  • @SometimesIFeelLike...Zipi:对不起。你是对的,我错了你没有打电话给grid。我更新了我的答案。我认为现在完全正确。
  • 是的,现在是正确的,但我不明白为什么它需要调用 '.lift()' 以使其在独立代码中工作,为什么不在我的完整应用程序中.答案就在你写的关于堆叠顺序的某个地方,但我无法弄清楚:)
【解决方案2】:

终于搞定了。首先很抱歉我没有先发布独立的可运行代码。当我将代码放入文件并对丢失的变量进行必要的更改时,建议的.lift() 方法起作用了。原因是在那个单一文件中,我使用了根窗口作为父窗口。

在我复制的代码中,两个标签(id_numid_num2)有一个父级画布(result_area_leaf),这就是问题所在。如果我将根窗口作为传递的小部件的父窗口,则会显示小部件。毕竟.lift()其实是不需要的。

谢谢大家 ;)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-17
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    • 2019-03-15
    • 1970-01-01
    • 2021-05-29
    • 2019-04-23
    相关资源
    最近更新 更多