问题
I'm looking to implement a top level window which has a controllable number of label widgets on it. In my first window, there is a scale widget which you can use to select the number of labels on the top level. These labels then need to be updated in real time. I have code for generating the top level window, as well as for dynamically updating one label on it using the After utility.
I can't figure out how to produce a variable set of labels which I can then update later in the code. My first thought is to do something like so:
for i in range(n):
label = Label(top_level, text = "Text")
label.pack()
The issue with this is how it generates the same label n times and that means you can't update them independently (or at all). This means I can't implement my after argument to update them with real-time data. What is the correct way to approach this problem?
回答1:
The issue with this is how it generates the same label n times
This is incorrect. You do create n different labels, but in every iteration of the loop you overwrite the reference to the previous label. Therefore, when the loop ends, you have a reference to only the last label.
What you can do is save the different labels in a list. That way, you can access them individually using their index:
from tkinter import *
top_level = Tk()
n = 5
label_list = []
for i in range(n):
label_list.append(Label(top_level, text = "Text"))
label_list[i].pack()
for i in range(n):
label_list[i].config(text="Text {}".format(i))
top_level.mainloop()
回答2:
Question: how to produce a variable set of labels which I can then update later in the code
The following example allows to update all Labels in a Toplevel widget.
Note: If you have also other widgets in your
Toplevel, use aFramefor theLabel's and loop theself.frame.children.
The data to update, has to be a dict with predefined keys.
import tkinter as tk
from collections import OrderedDict
class Toplevel(tk.Toplevel):
def __init__(self, parent, label_dict):
super().__init__(parent)
for key, text in label_dict.items():
label = tk.Label(self, text=text)
label.key = key
label.pack()
def update_labels(self, data):
children = self.children
for c in children:
label = children[c]
label.configure(text=data[label.key])
class App(tk.Tk):
def __init__(self):
super().__init__()
self.menubar = tk.Menu()
self.menubar.add_command(label='Update', command=self.update)
self.labels = OrderedDict({'label_1':'Label 1', 'label_2':'Label 2', 'label_3':'Label 3'})
self.top = Toplevel(self, self.labels)
def update(self):
for key, text in self.labels.items():
self.labels[key] = 'Updated {}'.format(text)
self.top.update_labels(self.labels)
if __name__ == "__main__":
App().mainloop()
Tested with Python: 3.5
来源:https://stackoverflow.com/questions/55104813/using-tkinter-to-produce-n-labels-where-n-is-variable