2011-11-24 45 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