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
調試的第一步總是驗證您的假設。 –