Проблемы с перенаправлением выходного текста в отдельное окно в PythonPython

Программы на Python
Ответить
Anonymous
 Проблемы с перенаправлением выходного текста в отдельное окно в Python

Сообщение Anonymous »

Я очень, очень новичок в программировании, только что закончил семестровый курс Python. Я хотел взять существующую программу, которую я написал для своего класса, и перенаправить весь выводимый текст в отдельное окно вместо программного терминала. Я следовал руководству, но у меня возникли проблемы с фактическим получением выходного текста в созданное окно. Обе программы работают нормально по отдельности, но просто не связаны друг с другом.
Я думал, проблема в том, что моя исходная программа требует ввода данных пользователем, поэтому при запуске полной программы исходная программа должна сначала завершиться в терминале, а затем откроется окно (все еще пустое).
Это код, который я написал, следуя приведенному выше руководству:
import tkinter as tk
from tkinter import scrolledtext
import sys
import io

class TextWidgetStream(io.TextIOBase):
def __init__(self, text_widget, tag="stdout"):
super().__init__()
self.text_widget = text_widget
self.tag = tag # Tag for coloring

def write(self, s):
self.text_widget.after(0, self._insert_text, s)

def _insert_text(self, s):
self.text_widget.config(state='normal')
self.text_widget.insert('end', s, (self.tag,))
self.text_widget.see('end') #Auto-scroll to bottom
self.text_widget.config(state='disabled')

def flush(self):
pass #Required for stream compliance

class OutputRedirectorGUI:
def __init__(self, root):
self.root = root
self.root.title("Title")
self.root.geometry("800x600")

#Save original Streams
self.original_stdout = sys.stdout
self.original_stderr = sys.stderr

#Create and configure Text widget w/ scrollbar
self.text_widget = scrolledtext.ScrolledText(
root,
wrap=tk.WORD,
state=tk.DISABLED,
bg="#020501",
font=("Good Old DOS", 15)
)
self.text_widget.pack(padx=10, pady=10, fill = "both", expand=True)

#Configure tags for stdout(black) & stderr (red)
self.text_widget.tag_configure("stdout", foreground = "green4")
self.text_widget.tag_configure("stderr", foreground = "red")

# Redirect stdout and stderr:
self.stdout_redirector = TextWidgetStream(self.text_widget, tag="stdout")
self.stderr_redirector = TextWidgetStream(self.text_widget, tag="stderr")
sys.stdout = self.stdout_redirector
sys.stderr = self.stderr_redirector

#Restore streams on exit
self.root.protocol("WM_DELETE_WINDOW", self.on_exit)

def on_exit(self):
#Restore original streams before closing
sys.stdout = self.original_stdout
sys.stderr = self.original_stderr
self.root.destroy()

После этого моя исходная программа по сути представляет собой просто функцию def main() с циклом while, который выполняет различные операторы печати и ввода до завершения. После этого кода такой:
if __name__ == "__main__":
main()
root = tk.Tk()
app = OutputRedirectorGUI(root)
root.mainloop()

Поскольку я новичок в этом деле, я просто иду методом проб и ошибок, следуя руководствам.
Изменить 15.05.26:
В конечном итоге я столкнулся с проблемами, поскольку моя существующая программа требовала ввода пользователя, но с помощью, приведенной ниже, я смог перенаправить выходной текст в окно Tkinter! Для тех, кто еще попытается сделать что-то подобное и встретит этот пост в будущем, вот код, который в конечном итоге сработал у меня:
import io
import tkinter as tk
import threading
from tkinter import ttk
from tkinter import scrolledtext
import sys

class TextWidgetStream(io.TextIOBase):
def __init__(self, text_widget, tag="stdout"):
super().__init__()
self.text_widget = text_widget
self.tag = tag # Tag for coloring
def write(self, s):
self.text_widget.after(0, self._insert_text, s)
def _insert_text(self, s):
self.text_widget.config(state="normal")
self.text_widget.insert("end", s, (self.tag,))
self.text_widget.see("end") # Auto-scroll to bottom
self.text_widget.config(state="disabled")
def flush(self):
pass # Required for stream compliance
def start_other_process(function_name):
# it may need `daemon=True` to stop thread if window will be closed before end of thread.
p = threading.Thread(target=function_name, daemon=True)
p.start()

original_stdout = sys.stdout
original_stdin = sys.stdin
# ----- Tkinter Window Settings -----
root = tk.Tk()
root.title("Title")
root.geometry("800x600")
#Frame/border:
custom_frame = tk.Frame(root)
custom_frame.pack(fill='x')
root.tk_setPalette(background='#020501')

#Text widget w/ scrollbar
text_widget = scrolledtext.ScrolledText(
root,
wrap=tk.WORD,
state=tk.DISABLED,
bg="#020501",
font=("Arial", 10)
)
text_widget.pack(padx=10, pady=10, fill = "both", expand = True)
text_widget.tag_configure("stdout", foreground="green4")
text_widget.tag_configure("stderr", foreground="red4")
text_widget.tag_configure("stdin", foreground="red")

sys.stdout = TextWidgetStream(text_widget, "stdout")
sys.stdin = TextWidgetStream(text_widget, "stdin")
# it will start thread with`main()` 100ms after starting `mainloop()`
root.after(100, start_other_process, main)
root.mainloop()
sys.stdout = original_stdout
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»