繁体   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