I found a way to use a future from concurrent.futures library. This is a gui program that will allow you to scroll and hit the wait button when you are still waiting for STDIN. Whenever the program sees it has a line of information from STDIN then it will print it in the multi-line box. But it does not lock the script lock out the user from the gui interface why it is checking stdin for a new line. (Please note I tested this in python 3.10.5)
import concurrent.futures import PySimpleGUI as sg import sys def readSTDIN(): return sys.stdin.readline() window = sg.Window("Test Window", [[sg.Multiline('', key="MULTI", size=(40, 10))], [sg.B("QUIT", bind_return_key=True, focus=True), sg.B("Wait")]], finalize=True, keep_on_top=True) for arg in sys.argv[1:]: window["MULTI"].print(f"ARG={arg}") with concurrent.futures.ThreadPoolExecutor() as pool: futureResult = pool.submit(readSTDIN) while True: event, values = window.read(timeout=500) if event != "__TIMEOUT__": window['MULTI'].print(f"Received event:{event}") if event in ('QUIT', sg.WIN_CLOSED): print("Quit was pressed") window.close() break if futureResult.done(): # flag that the "future" task has a value ready; #therefore process the line from STDIN x = futureResult.result() window["MULTI"].print(f"STDIN:{x}") futureResult = pool.submit(readSTDIN) #add a future for next line of STDIN
os.isatty(0)checks if the file associated to the file descriptor (fd) 0 is a TTY. When you change thesys.stdinvariable, you're not changing the file associated with fd0. fd0 is still pointing to the original stdin (which is a TTY in your case).cStringIO.StringIO("ddd")could block; it always has data available, except when EOF is reached of course.