在GUI-PySimpleGUI的窗口中显示CMD控制台



我正在使用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=Truereroute_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在长时间打印时停止工作,此处需要mutlithread。在事件循环期间,它将不适用于实时打印,因为循环正在处理您的打印语句,完成后返回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()

最新更新