【问题标题】:Python/Tkinter: Loop iterations not completingPython/Tkinter:循环迭代未完成
【发布时间】:2012-01-07 19:41:47
【问题描述】:

在以下情况下,我尝试将 temp2 脚本(通过子进程运行)的所有输出实时打印到文本框小部件。

我面临的问题是,在 temp2 中,i <= 468 的脚本运行良好,对我来说它似乎是实时的。

但是,如果我输入i = 469 或更高版本,执行会在多次迭代后停止。

例如,对于i = 469,日志文件包含i = 469i = 3 的条目。在整个过程停止之后。

请注意:i = 469 可能与您的机器不同。如果i = 469 适合您,请尝试更高的值。

Temp1.py 是主脚本。

#temp1.py
from Tkinter import *
import Tkinter as tk
import os
import ttk 
os.system('echo OS ready')
os.system('chmod 755 *')
import subprocess
import sys

#Creating new Window to display output 
t = Tk()
t.title('output Run Display')
t.geometry('800x1000-5+40')
t.state('normal')
little = Label(t, text="NRUNTEST 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('temp2',shell=True,stdout=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()
t.mainloop()

下面是我在子进程中运行的脚本。

#temp2 #csh script

set i = 469
while ($i > 0)
  echo i is $i | tee -a log
  set i = `expr "$i" - 1`
end 

【问题讨论】:

  • else: 行是否正确缩进?下面的行似乎也无效......
  • 在我的解释器中没问题,这里纠正了一些由于从 unix 复制粘贴到窗口机器而导致的缩进错误

标签: python loops textbox tkinter subprocess


【解决方案1】:

作为 jsbueno 的回答,您的问题来自阻止对 readline 的调用。您可以改为使用文件事件源在数据可用时获得通知(通过createfilehandler tkinter 方法)。详情请见this previous answer

【讨论】:

    【解决方案2】:
    import os
    import ConfigParser
    from Tkinter import *
    import Tkinter as tk
    import os
    import ttk 
    os.system('echo OS ready')
    os.system('chmod 755 *')
    import subprocess
    from subprocess import call
    import sys
    
    os.system('rm stdout')
    
    #Creating new Window to display output 
    t = Tk()
    t.title('output Run Display')
    t.geometry('100x100')
    t.state('normal')
    little = Label(t, text="NRUNTEST OUTPUT LOG").grid(column = 0, row = 0)
    log = Text(t, state='disabled', width=50, height=50, wrap='none')
    log.grid(row = 1, column = 0,sticky=(N,W,E,S))
    s = ttk.Scrollbar(t,orient=VERTICAL,command=log.yview)
    s.grid(column=1,row=1,sticky=(N,S))
    log.configure(yscrollcommand=s.set)
    ttk.Sizegrip().grid(column=1, row=1, sticky=(S,E))
    
    with open("stdout","wb") as out:
        with open("stderr","wb") as err:
            test=subprocess.Popen('tem',shell=True,stdout=out,stderr=err)
    fout = open('stdout','r')
    ferr = open('stderr','r') 
    def verify():
    
        data_out = fout.readlines()
        data_out = ''.join(data_out)
    
        log['state'] = 'normal'
        log.insert('end',data_out)
        log['state'] = 'disabled'
        #print data_out
    
        t.after(1000,verify)
        fout.close()
    
    verify()
    
    t.mainloop()
    

    【讨论】:

      【解决方案3】:

      您的问题是对 test.stdout.readline 的调用被阻塞 - 这意味着处理将在那里停止,并且只有在返回新的可用数据行时才会恢复。

      test.stderr.readline 当然也是如此。

      我认为处理您想要的最简单的方法是让您的子进程写入文件系统上的文件,您在主进程上打开该文件,并尝试在定期调用的 tkinter 回调函数中读取它.aftertkinter 方法。

      (文件系统上有文件,您可以使用seektell 方法检查您是否在文件末尾)

      请注意,在您作为示例放置的代码中,您对 Tkinter.mainloop 的调用只有在子进程已经耗尽后才能到达。

      更好的解决方案是完全在 Python 中读取您想要的日志,而不依赖于 shell 脚本。

      Tkinter.after 类似于 javascript 的 settimeout - 它是一个小部件上的方法(例如,您的“t”对象),您将等待的毫秒数和要调用的函数的名称传递给它 -

      喜欢

      def verify_output():
          # read subprocess output file and update the window if needed
          ...
          # call self after 1 second
          t.after(1000, verify_output)
      
      # callreader callback for the first time:
      
      t.after(10, verify_output)
      Tkinter.mainloop()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-22
        • 2021-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多