0
我的目标是从shell中的youtube-dl获得状态的实时输出,并将其作为tkinter中的标签。这可能是这样做的最糟糕的方式(即使它现在不工作),所以我不介意有人想出一个更好的方法来做到这一点。Python 3 - 在Tkinter中获取cmd的实时输出
我用另一个问题尝试了几件事(Getting realtime output using subprocess),但我没有得到它的工作。
import subprocess
import sys
import tkinter as tk
from threading import Thread
master = tk.Tk()
link = "https://www.youtube.com/watch?v=AC-3RJHzEU8"
def start_thread():
t = Thread(target = download)
t.start()
def download():
global text_var
cmd = "youtube-dl -x --audio-format mp3 {0}".format(link)
process = subprocess.Popen(cmd,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell = True)
while True:
out = process.stdout.read(1)
if out == '' and process.poll() != None:
break
if out != '':
text_var.set(sys.stdout.write(out.decode('utf-8')))
sys.stdout.flush()
text_var = tk.StringVar()
text_var.set("Status")
tk.Button(master, text = "Download", command = start_thread).pack()
tk.Label(master, textvariable = text_var).pack()
tk.mainloop()
解决方法:
我需要改变了一点,但它与杜尚Atanackovic的答案工作。 (我也用了Textwidget,因为它的方式比标签更好)
import subprocess
import tkinter as tk
from threading import Thread
master = tk.Tk()
def sudo(cmd, terminal):
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1, universal_newlines=True, shell = True)
p.poll()
while True:
line = p.stdout.readline()
terminal.insert(tk.END, line)
terminal.see(tk.END)
if not line and p.poll is not None: break
while True:
err = p.stderr.readline()
terminal.insert(tk.END, err)
terminal.see(tk.END)
if not err and p.poll is not None: break
terminal.insert(tk.END, '\n Finished download')
textfield = tk.Text(master, font = "Arial 15")
textfield.pack()
link = "https://www.youtube.com/watch?v=s8XIgR5OGJc"
a = "youtube-dl --extract-audio --audio-format mp3 '{0}'".format(link)
t = Thread(target = lambda: sudo(a, textfield))
t.start()
tk.mainloop()
'sys.stdout.write函数(...)“可能不会返回您认为它所做的事情。也许你应该将结果保存到一个变量中,然后在调用'text_var.set'之前检查该变量以验证其中的内容。 –
嘿,谢谢你的回答。仍然没有得到正确的输出。 :/ – HealYouDown
调试的第一步总是验证您的假设。 –