在Tkinter中遍历小部件

5

以下是我考虑的问题:

在框架中我有许多类似的小部件(例如标签)。我在算法的每次迭代中更新它们(使用root.update()在相关函数中)。我想知道的是如何遍历每个标签。

当然,它们是用类似以下方式创建的:

self.var1=IntVar()
self.lab1=Label(frame,textvariable=self.var1)
self.lab1.grid() 

每个标签都被命名为lab1,lab2等。我相信有更好的命名方式,这样我就不必显式地调用每个名称,或者以某种方式循环它们。

3个回答

14

您始终如一的命名方案使您可以使用变量名来迭代访问变量:

for i in range(1,n):
    label = getattr(self, "lab"+str(i))

您可以考虑依赖于Tkinter,它保留了您的小部件树结构,可通过children小部件属性(一个字典)访问:

for child in frame.children.values():
    #do something to all children

如果您的窗口包含其他小部件,最终还可以添加一些过滤。例如,要过滤小部件的类:

for label in filter(lambda w:isinstance(w,Label), frame.children.itervalues()):
    #do something on labels

请注意,子元素之间的遍历顺序没有任何保证。如果需要这样的服务,请依赖于几何管理器信息,例如 pack_slavesgrid_slaves

for child in frame.pack_slaves():
    #traverse in pack addition order
#or
for child in reversed(frame.grid_slaves()):
    #traverse in grid addition order

1
最简单的方法是将每个小部件的引用存储在列表或字典中,而不是(或除了)标量实例变量。

你是指像这样的编程吗:list1=[self.var1,self.var2],然后循环遍历 list1[list] - sigma.z.1980
我知道这可能有点过时了,但它真的帮我省了很多时间。 - Cow

0
上述的答案并没有完全按照我的要求工作,所以我用Python 3.11通过递归地查找窗口/框架的所有子元素来完成了这个任务。
def IterateWindowWidgets(window):
    for widget in window.winfo_children():
        lastDot = str(widget).rfind('.')
        # The format of str(widget) is '!window.!frame.!widget', so this is to only
        # look at the lowest current widget in the hierarchy.
        if '!toplevel' in str(widget)[lastDot:] or '!frame' in str(widget)[lastDot:]:
            IterateWindowWidgets(widget)
        else:
            if '!label' in str(widget)[lastDot:]
                widget.yourCommandHere

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接