如何在文本小部件和控制台之间切换打印输出 (Python 3.11)

问题描述 投票:0回答:1

我想随意将打印输出发送到文本窗口或控制台。如果我开始发送到控制台,我的代码可以正常工作,但是一旦我输出到文本窗口,就无法输出回控制台。

这是我的代码:

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()
http-redirect text console widget output
1个回答
0
投票

要在控制台和 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()
© www.soinside.com 2019 - 2024. All rights reserved.