[英]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.我正在使用 Tkinter 制作一个运行我拥有的其他两个 python 脚本的 GUI。 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.我最初使用 Label 小部件执行此操作,它确实会在创建新行时更新并显示控制台。
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.我在网上搜索,发现 Tkinter 中有一个Text
小部件,但我现在遇到的问题是,无论我执行myText.update()
、 root.update()
还是两者,Text 小部件都不会更新。
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.再一次,它使用Label
小部件实时更新,但现在它是Text
小部件,它直到程序完成运行后才会更新。 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. @acw1668 的评论是对我有用的解决方案。 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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.