import sys
from tkinter import Text, END
class StdoutRedirector:
def __init__(self, text_widget: Text):
self.text_widget = text_widget
self.last_line_start = 0 # 跟踪最后一行的起始位置
def write(self, output: str):
if output.startswith('/r'):
# 去除前缀 '/r'
output = output[2:]
# 删除最后一行内容
if self.last_line_start != 0:
self.text_widget.delete(f"{self.last_line_start}.0", END)
# 插入新内容
self.text_widget.insert(END, output)
# 更新最后一行的起始位置
self.last_line_start = int(self.text_widget.index('end-1c').split('.')[0])
else:
# 正常写入
self.text_widget.insert(END, output)
if output.endswith('\n'):
self.last_line_start = int(self.text_widget.index('end-1c').split('.')[0]) + 1
else:
self.last_line_start = int(self.text_widget.index('end-1c').split('.')[0])
# 滚动到文本组件的末尾
self.text_widget.see(END)
def flush(self):
"""
刷新缓冲区,确保所有数据被立即写出。
对于Tkinter的Text组件来说,这通常意味着确保所有已写入的内容立即显示给用户。
"""
# 在Tkinter的Text组件中,实际上并没有真正的“刷新”概念,
# 因为写入操作是立即可见的。但为了保持接口一致性,我们仍然提供这个方法。
# 如果需要,这里可以添加代码来强制更新GUI。
self.text_widget.update_idletasks() # 强制刷新GUI,确保所有挂起的任务都被处理
# 示例用法
if __name__ == '__main__':
import tkinter as tk
root = tk.Tk()
text = tk.Text(root, wrap='word') # 设置wrap为'word'以防止单词被分割
text.pack(fill=tk.BOTH, expand=True)
# 重定向stdout到text widget
sys.stdout = StdoutRedirector(text)
# 测试
print("这是第一行")
print("/r这是替换后的第一行")
print("这是第二行")
root.mainloop()
04-28
6431

11-17
2631

06-28
8548

07-13
10万+

12-28
6194
