簡體   English   中英

Tkinter - 如何從子進程更新文本小部件?

[英]Tkinter - How to update Text widget from subprocess?

我正在使用 Tkinter 制作一個運行我擁有的其他兩個 python 腳本的 GUI。 我想將控制台打印到窗口。 我最初使用 Label 小部件執行此操作,它確實會在創建新行時更新並顯示控制台。

然而,當我意識到我無法滾動時,問題就出現了。 文本一直在顯示太多行,無法在窗口中顯示。 我在網上搜索,發現 Tkinter 中有一個Text小部件,但我現在遇到的問題是,無論我執行myText.update()root.update()還是兩者,Text 小部件都不會更新。

再一次,它使用Label小部件實時更新,但現在它是Text小部件,它直到程序完成運行才會更新。 如果我想向我的程序的用戶提供當前進程正在做什么的實時提要,這當然是一個問題。

這是我的參考代碼:

with subprocess.Popen(['python.exe','Test2.py'], stdout=subprocess.PIPE,
                      stderr=subprocess.STDOUT) as process:
    for line in process.stdout:
        text= line.decode('utf8')
        myText.insert(END, text)
        myText.update()

編輯:對於一些添加的上下文,這里是我的程序的其余部分(有一些編輯):

from tkinter import *
import subprocess
import threading as thread

root = Tk()
root.geometry('1280x720')
root.title("Run Other Programs GUI")
frame = Frame(root, width=1280).grid(row=0, column=2)
frame2 = Frame(root, width=1280).grid(row=1,column=2)
#Creating Labels
myLabel1 = Label(frame, text="Main Program").grid(row=0, column=2, sticky='')
myLabel2 = Label(frame, text="Side Program").grid(row=3, column=2, sticky='')
myText = Text(frame2)
myText.grid(row=6, column=2)
myLabel3 = Label(frame2, text='')
myLabel3.grid(row=7, column=2, sticky='')

def getText(line):
    text = line.decode('utf8')
    return text
def insertText(myText, text):
    myText.insert(END, text)


def appear(index):
    # Disable the button by index
    global myLabel3
    myLabel3.config(text="")
    buttons[index].config(text="Running Program...")
    buttons[0].config(state="disabled")
    buttons[1].config(state="disabled")
    root.update()
    if(index==0):
        with subprocess.Popen(['python.exe','Test2.py'], stdout=subprocess.PIPE,
                      stderr=subprocess.STDOUT) as process:
            for line in process.stdout:
                text= line.decode('utf8')
                myText.insert(END, text)
                myText.update()
        buttons[index].config(state="active")
        buttons[index].config(text="Click to run program")
        buttons[1].config(state="active")
        myLabel3.config(text="Finished Running Main Program!")
    elif(index==1): #need to work on this still
        subprocess.call(['python.exe',"Test1.py"])
        buttons[index].config(state="active")
        buttons[index].config(text="Click to run program")
        buttons[0].config(state="active")
        myLabel3.config(text="Finished Running Side Program!")
    else:
        print("Error, this shouldn't be happening, button index is not defined")

# A collection (list) to hold the references to the buttons created below
buttons = []

for index in range(2): 

    button = Button(frame, bg="White", text="Click to run program", width=50, height=3, relief=GROOVE,
                    command=lambda index=index: appear(index))

    # Add the button to the window
    button.grid(padx=2, pady=2, row=(index+1)*2, column=2, sticky='')

    # Add a reference to the button to 'buttons'
    buttons.append(button)

root.mainloop()

@acw1668 的評論是對我有用的解決方案。 以供參考:

with subprocess.Popen(['python.exe', '-u', 'Test2.py'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as process:
        for line in process.stdout:
            line = line.decode() # defaulting to system encoding
            myText.insert(END, line)
            myText.update()
            process.poll()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM