我有一段代码可以进行一些文本分析,并在tkinter窗口中显示结果。 由于用户可以选择对多个源进行相同的分析,这可能需要相当长的时间,因此我希望在结果可用时显示结果。 但是,只有在最后一个结果可用后才会弹出tkinter窗口。从Stackoverflow上的其他问题,我理解为什么这不起作用(我的代码的简化版本):
class Output:
def __init__(self):
self.set_main_variables()
def set_main_variables(self):
self.names= []
#and other variables...
def initialize(self):
self.t = Tk()
self.make_frames()
self.populate_frames()
self.t.mainloop()
def update(self):
self.populate_frames()
def populate_frames(self):
<uses the data in self.names to display the results>
output = Output()
for i, s in enumerate(sources):
results = analyze(s)
output.names = results
if i == 0:
output.initialize()
else:
output.update()
因此,我尝试将initialize()从循环中取出,并在窗口中创建一个按钮,用户可以通过该按钮更新结果(如果有的话):
output = Output()
first_results = analyze(s[0])
output.names = first_results
output.initialize()
for i, s in enumerate(sources):
results = analyze(s)
output.names = results
但这并没有解决问题;只有在分析完最后一个来源后,窗口才会弹出。
我已经阅读了许多可能的选项来处理这个问题(使用after,guiloop等),但我不知道这些可以在这种情况下如何帮助我。
有人能让我走上正确的道路吗?
答案 0 :(得分:0)
一位同事找到了我的问题的解决方案。
埃里克在评论中提到了我正确的道路。他建议在GUI中使用update_idletasks(),但这不起作用:它打开了一个空白窗口,只有在“sources”循环完成时才会填充小部件。 解决方案是将update()放在GUI内部,但放在将更新发送到GUI的循环中。 工作代码的简化示例:from tkinter import *
class SimpleTestClass:
def __init__(self):
self.names = []
self.top = Tk()
self.names_string = StringVar()
self.label = Label(self.top, textvar=self.names_string).pack()
#self.top.mainloop()
def updateLabel(self):
self.names_string.set("\n".join(self.names))
def test(gui):
names = ["a", "b", "c"]
sources = [11, 2, 3]
for i, s in enumerate(sources):
print(i)
gui.names.append(names[i])
print(gui.names)
gui.updateLabel()
gui.top.update()
#gui.top.update_idletasks()
time.sleep(3) # this simulates the program taking /
# some time to do its analysis of the source
s = SimpleTestClass()
test(s)
两个注释:
我还尝试了一个替代版本,用户可以按下按钮手动更新结果列表,但这不能很好地工作(按钮仅在完成源循环时才会响应):
class SimpleTestClass:
def __init__(self):
self.names = []
self.top = Tk()
self.names_string = StringVar()
self.label = Label(self.top, textvar=self.names_string).pack()
Button(self.top, text="update", command=self.updateLabel).pack()
def updateLabel(self):
self.names_string.set("\n".join(self.names))
def test(gui):
names = ["a", "b", "c"]
sources = [11, 2, 3]
for i, s in enumerate(sources):
gui.names.append(names[i])
print(gui.names)
gui.top.update()
time.sleep(3) # this simulates the program taking /
# some time to do its analysis of the source
s = SimpleTestClass()
test(s)