我需要知道在使用文本框显示大量数据时是否遇到过减速甚至挂起的问题。
在我的情况下,我使用子进程运行模拟脚本,其stdout显示在文本框中。 文本可以是MB。
我尝试了两种实现:
1)文本框在显示stdout数据之前等待模拟(子进程)完成。这个问题很好。 但唯一的问题是我想实时显示标准数据。
2)我开始实时显示数据 - 这里文本框很容易显示小进程的stdout数据。 但是,当我运行很长的模拟脚本时,它们会卡在两者之间。 我知道模拟脚本的执行会因为没有生成相关的输出文件而暂停。 屏幕挂起类似于我们在Windows中遇到的屏幕。
关于模拟脚本:这是一个单独的脚本,可以使用其他脚本运行许多其他子进程(一次一个)。
如果您有任何解决方案,请提供建议吗?我可以使用画布而不是文本框吗?会有帮助吗?
请找到如下运行功能:
def run():
filename = str(run_file_name.get())
command.set("Running "+filename)
#Creating new Window to display output
t = Toplevel(root)
t.title('output Run Display')
t.geometry('800x1000-5+40')
t.state('normal')
little = Label(t, text="OUTPUT LOG").grid(column = 0, row = 0)
log = Text(t, state='disabled', width=115, height=150, wrap='none')
log.grid(row = 1, column = 0)
test=subprocess.Popen(filename,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)# stderr=subprocess.PIPE)
#stdout
while True:
line_out = test.stdout.readline()
line_er = test.stderr.readline()
if line_out == "" and line_er == "":
break
else:
log['state'] = 'normal'
log.insert('end', line_out)
log.insert('end', line_er)
log['state'] = 'disabled'
print line_out
print line_er
t.update()
主要目标是运行子进程并在文本框上显示所有输出,从而将用户与命令提示符界面脱钩。 来自我的调试尝试备注: 当我用一个打印数字1到5000的示例脚本(sample_script)运行相同的gui脚本时,它运行正常。这意味着脚本的流程是可以的。 但是测试环境和我的实际脚本运行环境之间存在一个主要区别:那就是我的子进程运行脚本(例如: - script_1)实际上是一个父csh脚本,它运行其他脚本(例如: - script1.1和脚本1.2)它。 因此请注意以下几点:
当script1发出启动script1.1的命令时,执行暂停 sample_script(打印数字)工作正常。
调试更新: 我将以下脚本作为sample_script运行,并注意到以下结果:
set i = 450
while ($i > 1)
echo i is $i
set i = `expr "$i" - 1`
end
通过运行上面的例子,我发现只有在子进程完成后才会出现输出。 但是,在我的情况下,如果我把i = 550,终端保持等待状态并且输出不会出现(即使在很多分钟之后)。因此这个过程陷入僵局 i = 550的数字可能更高或更低。 当我运行i = 550时,使用print语句我发现sample_script的执行在i = 98处停止。 我无法弄明白为什么!!
如果您需要更多信息,请提示我。
答案 0 :(得分:2)
我已经使用了近20年的tk并且没有注意到大量文本的任何问题,尽管我不认为我曾试图加载超过几十万行的数量。您想要显示多少数据?您使用的是大量标签和不同的字体,还是只是纯文本?
当然,如果您正在生成子进程并等待它完成,整个GUI将无法响应。 Tk是单线程的,所以当你等待一个进程完成时,没有办法让事件循环运行,因此你的程序会冻结。您需要确保用于运行流程和管理其输出的任何方案都不会阻止事件循环。
我的猜测是,这不是文本小部件的限制,切换到画布也无济于事。问题可能在于您的代码,但如果没有看到您的代码,则无法提出解决方案。
答案 1 :(得分:0)
作为一种解决方法,也许不是实时显示整个输出,而是实时显示最后100行?如有必要,仍可将完整输出放入日志文件中以便稍后加载。