嘿,我想在 tk.Text 小部件中將子行程的輸出顯示到我的 GUI 中。我有一個代碼,它作業得很少,但它不是實時的。如何實作終端的輸出將實時寫入文本小部件???
import tkinter as tk
import subprocess
import threading
#### classes ####
class Redirect():
def __init__(self, widget, autoscroll=True):
self.widget = widget
self.autoscroll = autoscroll
def write(self, textbox):
self.widget.insert('end', textbox)
if self.autoscroll:
self.widget.see('end') # autoscroll
def flush(self):
pass
def run():
threading.Thread(target=test).start()
def test():
p = subprocess.Popen("python myprogram.py".split(), stdout=subprocess.PIPE, bufsize=1, text=True)
while p.poll() is None:
msg = p.stdout.readline().strip() # read a line from the process output
if msg:
print(msg)
##### Window Setting ####
fenster = tk.Tk()
fenster.title("My Program")
textbox = tk.Text(fenster)
textbox.grid()
scrollbar = tk.Scrollbar(fenster, orient=tk.VERTICAL)
scrollbar.grid()
textbox.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=textbox.yview)
start_button= tk.Button(fenster, text="Start", command=run),
start_button.grid()
old_stdout = sys.stdout
sys.stdout = Redirect(textbox)
fenster.mainloop()
sys.stdout = old_stdout
uj5u.com熱心網友回復:
歡迎堆疊溢位。我稍微修改了您的代碼(您,在定義之后start_button沒有匯入sys,我也將您的代碼放在下面##### Window Setting ####的樣板代碼中)。
您的主要問題是,您沒有使您的Text小部件在您的run以及您的test函式中可用(作為執行緒執行)。因此,我將您的小部件作為兩個函式的引數移交給了兩個函式(但是,這可能不是最 Pythonic 的方式)。為了執行系結到按鈕的命令,我使用from functools import partial并系結了包含引數的命令command=partial(run, textbox)。然后我簡單地將引數交給run執行緒,args=[textbox]在您創建和啟動執行緒的行中。最后,我textbox.insert(tk.END, msg "\n")在您的test函式中更新了文本框,同時洗掉了print(). 插入將末尾的任何文本附加到文本框,"\n"開始一個新行。
這是(稍微重組的)完整代碼(app.py):
import tkinter as tk
import subprocess
import threading
import sys
from functools import partial
# ### classes ####
class Redirect:
def __init__(self, widget, autoscroll=True):
self.widget = widget
self.autoscroll = autoscroll
def write(self, textbox):
self.widget.insert('end', textbox)
if self.autoscroll:
self.widget.see('end') # autoscroll
def flush(self):
pass
def run(textbox=None):
threading.Thread(target=test, args=[textbox]).start()
def test(textbox=None):
p = subprocess.Popen("python myprogram.py".split(), stdout=subprocess.PIPE, bufsize=1, text=True)
while p.poll() is None:
msg = p.stdout.readline().strip() # read a line from the process output
if msg:
textbox.insert(tk.END, msg "\n")
if __name__ == "__main__":
fenster = tk.Tk()
fenster.title("My Program")
textbox = tk.Text(fenster)
textbox.grid()
scrollbar = tk.Scrollbar(fenster, orient=tk.VERTICAL)
scrollbar.grid()
textbox.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=textbox.yview)
start_button = tk.Button(fenster, text="Start", command=partial(run, textbox))
start_button.grid()
old_stdout = sys.stdout
sys.stdout = Redirect(textbox)
fenster.mainloop()
sys.stdout = old_stdout
這是我創建的測驗檔案myprogram.py的代碼:
import time
for i in range(10):
print(f"TEST{i}")
time.sleep(1)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/437490.html
