我想随意将打印输出发送到文本窗口或控制台。如果我开始发送到控制台,我的代码可以正常工作,但是一旦我输出到文本窗口,就无法输出回控制台。
这是我的代码:
from tkinter import *
from tkinter import scrolledtext
import sys
def redir(text):
Twidg.insert(INSERT,text); Twidg.yview(END)
def aff_widg():
Twidg.configure(state = "normal")
sys.stdout.write = redir
print("Contenu de la BD:\n")
Twidg.configure(state = "disabled")
def aff_cons():
# sys.stdout = sys.__stdout__
sys.stdout = original
print("Contenu de la BD:\n")
fen = Tk()
fenpr = Toplevel(fen)
fenpr.geometry("200x100+250+20")
original = sys.stdout
Twidg = scrolledtext.ScrolledText(fenpr, wrap = WORD,\
height = 20, width = 100)
Twidg.place(x=10,y=10)
Button(fen, text = "To Textwidg", command = aff_widg).pack()
Button(fen, text = "To console", command = aff_cons).pack()
fen.mainloop()
要在控制台和 Tkinter Text 小部件之间动态切换打印输出,您需要实现自定义标准输出重定向器并正确管理原始标准输出。关键是创建一个模仿 stdout 接口的 TextRedirector 类:
class TextRedirector:
def __init__(self, widget):
self.widget = widget
def write(self, text):
self.widget.configure(state="normal")
self.widget.insert(END, text)
self.widget.yview(END)
self.widget.configure(state="disabled")
def flush(self):
pass
在任何重定向之前存储原始标准输出:
original_stdout = sys.stdout
text_redirector = TextRedirector(text_widget)
然后创建简单的函数来在输出之间切换:
def to_widget():
sys.stdout = text_redirector
def to_console():
sys.stdout = original_stdout
为了测试,您可以添加一个打印定期消息的后台线程:
def print_messages():
counter = 1
while True:
print(f"Message {counter} at {datetime.now().strftime('%H:%M:%S')}\n")
counter += 1
time.sleep(1)
print_thread = threading.Thread(target=print_messages, daemon=True)
print_thread.start()
我的完整代码如下所示:
import sys
from tkinter import *
from tkinter import scrolledtext
import threading
import time
from datetime import datetime
class TextRedirector:
def __init__(self, widget):
self.widget = widget
def write(self, text):
self.widget.configure(state="normal")
self.widget.insert(END, text)
self.widget.yview(END)
self.widget.configure(state="disabled")
def flush(self):
pass
def print_messages():
counter = 1
while True:
current_time = datetime.now().strftime("%H:%M:%S")
print(f"Message {counter} at {current_time}\n")
counter += 1
time.sleep(1)
def to_widget():
sys.stdout = text_redirector
print("Switched to Text Widget output\n")
def to_console():
sys.stdout = original_stdout
print("Switched to Console output\n")
# Create main window
root = Tk()
root.title("Output Redirector")
root.geometry("200x100")
# Create text widget window
text_window = Toplevel(root)
text_window.title("Output Window")
text_window.geometry("600x400")
# Create and pack the text widget
text_widget = scrolledtext.ScrolledText(text_window, wrap=WORD, height=20, width=60)
text_widget.pack(padx=10, pady=10, expand=True, fill=BOTH)
# Store original stdout and create redirector
original_stdout = sys.stdout
text_redirector = TextRedirector(text_widget)
# Create control buttons
Button(root, text="To Widget", command=to_widget).pack(pady=5)
Button(root, text="To Console", command=to_console).pack(pady=5)
# Start periodic printing in background
print_thread = threading.Thread(target=print_messages, daemon=True)
print_thread.start()
root.mainloop()