在 GUI 的 window 中显示 CMD 控制台 - PySimpleGUI
display the CMD console in a window in GUI - PySimpleGUI
我正在使用 PySimpleGUI 创建一个 GUI,并希望有一个框架来显示程序中所有函数的输出打印(如在 cmd 控制台中)。
我尝试使用(相关代码行):
def hello():
print('hello')
layout = [[sg.Frame("Output console", [[sg.Text(" ", size=(0, 1), key='-OUTPUT-')]])]]
window['-OUTPUT-'].update(hello())
我可以在控制台中看到打印,但在 GUI 的框架中看不到。
我该怎么做?
要像在 CMD 控制台中一样显示输出,您应该使用 sg.Multiline
,而不是 sg.Text
,它只是一个标签。
要重定向 stdout 和 stderr 的输出,设置选项 reroute_stdout=True
和 reroute_stderr=True
,同时设置选项 autoscroll=True
以在元素末尾添加更多数据时自动滚动。
演示代码 - GUI 将仅更新回 window.read
import PySimpleGUI as sg
def hello():
print('hello')
frame_layout = [[sg.Multiline("", size=(80, 20), autoscroll=True,
reroute_stdout=True, reroute_stderr=True, key='-OUTPUT-')]]
layout = [
[sg.Frame("Output console", frame_layout)],
[sg.Push(), sg.Button("Say Hello")],
]
window = sg.Window("Title", layout, finalize=True)
while True:
event, values = window.read()
if event == sg.WINDOW_CLOSED:
break
elif event == "Say Hello":
hello()
window.close()
要实时更新GUI,可以调用update(value, append=True)
和window.refresh
,不要使用print
语句,或者
以下代码显示了立即打印到 sg.multiline
的方法。为了避免停止 GUI 长时间打印,这里需要多线程。它不适用于事件循环期间的实时打印,因为循环正在处理您的打印语句,然后在完成后返回 window.read。
比较复杂,不知道有没有bug
import sys
from time import sleep
from datetime import datetime
import threading
import PySimpleGUI as sg
def print_task():
global printing
while printing:
print(datetime.now().strftime("%H-%M-%S"), datetime.now().strftime("%H-%M-%S"))
sleep(0.5)
class Unbuffered(object):
def __init__(self, window):
self.window = window
def write(self, data):
self.window.write_event_value("OUT", data)
def writelines(self, datas):
self.window.write_event_value("OUT", ''.join(datas))
frame_layout = [[sg.Multiline("", size=(80, 20), autoscroll=True, key='-OUTPUT-')]]
layout = [
[sg.Frame("Output console", frame_layout)],
[sg.Push(), sg.Button("Print"), sg.Button('Stop')],
]
window = sg.Window("Title", layout, finalize=True)
old_stdout, old_stderr = sys.stdout, sys.stderr
sys.stdout = Unbuffered(window)
sys.stderr = Unbuffered(window)
printing = False
while True:
event, values = window.read()
if event == sg.WINDOW_CLOSED:
break
elif event == 'Print':
if not printing:
printing = True
threading.Thread(target=print_task, daemon=True).start()
elif event == 'Stop':
printing = False
elif event == "OUT":
window['-OUTPUT-'].update(values["OUT"], append=True)
printing = False
sys.stdout, sys.stderr = old_stdout, old_stderr
window.close()
我正在使用 PySimpleGUI 创建一个 GUI,并希望有一个框架来显示程序中所有函数的输出打印(如在 cmd 控制台中)。 我尝试使用(相关代码行):
def hello():
print('hello')
layout = [[sg.Frame("Output console", [[sg.Text(" ", size=(0, 1), key='-OUTPUT-')]])]]
window['-OUTPUT-'].update(hello())
我可以在控制台中看到打印,但在 GUI 的框架中看不到。 我该怎么做?
要像在 CMD 控制台中一样显示输出,您应该使用 sg.Multiline
,而不是 sg.Text
,它只是一个标签。
要重定向 stdout 和 stderr 的输出,设置选项 reroute_stdout=True
和 reroute_stderr=True
,同时设置选项 autoscroll=True
以在元素末尾添加更多数据时自动滚动。
演示代码 - GUI 将仅更新回 window.read
import PySimpleGUI as sg
def hello():
print('hello')
frame_layout = [[sg.Multiline("", size=(80, 20), autoscroll=True,
reroute_stdout=True, reroute_stderr=True, key='-OUTPUT-')]]
layout = [
[sg.Frame("Output console", frame_layout)],
[sg.Push(), sg.Button("Say Hello")],
]
window = sg.Window("Title", layout, finalize=True)
while True:
event, values = window.read()
if event == sg.WINDOW_CLOSED:
break
elif event == "Say Hello":
hello()
window.close()
要实时更新GUI,可以调用update(value, append=True)
和window.refresh
,不要使用print
语句,或者
以下代码显示了立即打印到 sg.multiline
的方法。为了避免停止 GUI 长时间打印,这里需要多线程。它不适用于事件循环期间的实时打印,因为循环正在处理您的打印语句,然后在完成后返回 window.read。
比较复杂,不知道有没有bug
import sys
from time import sleep
from datetime import datetime
import threading
import PySimpleGUI as sg
def print_task():
global printing
while printing:
print(datetime.now().strftime("%H-%M-%S"), datetime.now().strftime("%H-%M-%S"))
sleep(0.5)
class Unbuffered(object):
def __init__(self, window):
self.window = window
def write(self, data):
self.window.write_event_value("OUT", data)
def writelines(self, datas):
self.window.write_event_value("OUT", ''.join(datas))
frame_layout = [[sg.Multiline("", size=(80, 20), autoscroll=True, key='-OUTPUT-')]]
layout = [
[sg.Frame("Output console", frame_layout)],
[sg.Push(), sg.Button("Print"), sg.Button('Stop')],
]
window = sg.Window("Title", layout, finalize=True)
old_stdout, old_stderr = sys.stdout, sys.stderr
sys.stdout = Unbuffered(window)
sys.stderr = Unbuffered(window)
printing = False
while True:
event, values = window.read()
if event == sg.WINDOW_CLOSED:
break
elif event == 'Print':
if not printing:
printing = True
threading.Thread(target=print_task, daemon=True).start()
elif event == 'Stop':
printing = False
elif event == "OUT":
window['-OUTPUT-'].update(values["OUT"], append=True)
printing = False
sys.stdout, sys.stderr = old_stdout, old_stderr
window.close()