2011-11-24 26 views
0

我需要知道,如果您在使用文本框显示大量数据时遇到了放缓甚至挂起的情况。你面对文本框没有响应?

在我的情况下,我正在运行一个使用子进程的模拟脚本,它的stdout显示在文本框中。 文本可以以MB为单位。

我试图两种实现:

1)文本框等待模拟(子过程)完成之前它可以显示标准输出数据。这工作得很好。 但唯一的问题是,我想要实时显示标准输出数据。

2)我开始实时显示数据 - 这里的文本框很容易显示小过程的标准输出数据。 但是,当我运行很长的模拟脚本时,它们被卡在两者之间。 我知道仿真脚本的执行被暂停,因为没有生成相关的输出文件。 屏幕挂起与我们在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() 

主要目标是运行的子进程并显示所有文本框上的输出,因此,以从脱钩命令提示接口用户。 从我的调试尝试 备注当我运行相同的GUI脚本与示例脚本(sample_script)打印数字1到5000,它运行良好。这意味着脚本的流程是可以的。 但测试环境和我的实际脚本运行环境之间有一个主要区别:那就是我的子进程运行脚本(例如: - 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时,使用打印语句,我发现sample_script的执行停在i = 98。 我无法弄清楚为什么!

如果您需要任何信息,请提示我。

回答

2

我已经使用了tk接近20年,并没有发现任何问题与大量的文字,但我不认为我曾经尝试加载超过几十几十的数千线。你试图展示多少数据?你使用了大量的标签和不同的字体,还是只是纯文本?

当然,如果您产生了一个子进程并等待它完成,整个GUI将会变得无响应。 Tk是单线程的,所以当你等待一个进程完成时,事件循环无法运行,因此你的程序将会冻结。您需要确保无论您使用哪种方案运行流程并管理其输出都不会阻止事件循环。

我的猜测是,这不是文本小部件的限制,切换到画布不会有帮助。问题可能出现在您的代码中,但没有看到您的代码,就不可能提出解决方案。

+0

嘿布莱恩。感谢您的评论。代码非常庞大,让我花些时间修改它以发布重要摘要。 – Ani

+0

Para2: 关于你对gui变得反应迟钝的评论..我试图运行一个示例脚本(使用子进程)。该脚本是从1到5000的循环打印编号。 在我的gui脚本的运行函数中,我正在运行一个循环(如果stdout和stderr没有结束)将流的内容传递给文本框。最后,我刷新了列表框小部件,它更新了新信息。 因此,循环取决于流值而不是子流程事件。 – Ani

+0

Para1:不,我没有使用任何标签和花哨的字体。我的输出通常是从stdout和stderr流接收的最多25k行。 – Ani

0

作为一种解决方法,或许不是实时显示整个输出,而是实时显示最后100行?完整的输出仍然可以放入日志文件中,以便稍后加载。

+0

嘿Shish,我的要求声明我用子文本的文本框替换终端。最后,如果我找不到任何解决方案,我将不得不按照您的建议显示较少量的数据。 – Ani