简体   繁体   中英

Tkinter - How to update Text widget from subprocess?

I am using Tkinter to make a GUI that runs two other python scripts that I have. I wanted to print out the console to the window. I did this initially with a Label widget, and it did update and show the console as new lines were created.

Problems arose, however, when I realized that I couldn't scroll with that. The text kept making too many lines to display within the window. I searched online and found that there was a Text widget in Tkinter, but the problem I have now is that the Text widget does not update regardless if I do myText.update() , root.update() , or both.

Once again, it updated in real time with the Label widget, but now that its the Text widget it doesn't update until after the program has finished running. This is of course an issue if I want to give the users of my program a live feed of what the current process is doing.

Here is my code for reference:

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()

Edit : For some added context here is the rest of my program (with some edits):

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's comment was the solution that worked for me. For reference:

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM