You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Textual application having problems resizing when importing readline
I have developed a Textual-based application that I want to integrate into my main application. I am facing some problems because my main application is calling import readline, which is breaking the Textual application's resizing capabilities.
Some context
I have built a TUI using Textual, and now I would like to attach it to my main application.
The main application is going to be running some code, such as printing information to stdout and writing to files.
What I would like to do is to launch the main application, which itself launches the Textual application, and does so without blocking the main application's code.
Additionally, it would be ideal if once I quit the textual application, it restores the stdout to be what it would have been if the textual application was never launched.
Basically I want something like this:
importtimefromdatetimeimportdatetimefrompathlibimportPathfromtextual.appimportApp, ComposeResultfromtextual.widgetsimportStaticclassDummyApp(App):
defcompose(self) ->ComposeResult:
for_inrange(15):
yieldStatic("This is a dummy Test GUI")
file_path=Path("some-file.txt")
launch_app=TruewhileTrue:
# This is the main application's code doing some workprint("Hello, doing work from the main application")
file_path.write("Hello, main application writing to file")
iflaunch_app:
launch_app=False# don't re launch app after# HERE start textual applicationapp=App()
app.run()
time.sleep(5) # simulate expensive workload
Solution I came up with and it's problem
In order to launch a textual app without block the rest of the application's code, the main application launches a Thread. That thread will make a call to subprocess.Popen to run the textual application.
The code roughly looks like this:
importsubprocessimportthreadingimporttimefromdatetimeimportdatetimefrompathlibimportPathfromtextual.appimportApp, ComposeResultfromtextual.widgetsimportStaticclassDummyApp(App):
defcompose(self) ->ComposeResult:
for_inrange(15):
yieldStatic("This is a dummy Test GUI")
defrun_textual_app():
process=subprocess.Popen(["python3", "app.py"]) # where app.py launches the DummyApp via app.run()process.wait()
file_path=Path("some-file.txt")
launch_app=TruewhileTrue:
print("Hello, world!") # simulating doing work in the main applicationfile_path.write("Hello, world!") # writing to files tooiflaunch_app:
launch_app=False# don't re launch app afterthreading.Thread(target=run_textual_app).start()
time.sleep(5) # simulate expensive workload
This partially works, as it does allow to launch the textual application without blocking the main application, however it causes problems because the main application is writing to stdout:
Fix for the stdout problem
My idea for this problem was to use os.dup2 to switch the file descriptors of the main application to write to a temporary file instead of writing to stdout.
I did this via :
importosimportsysimportsubprocessdefrun_textual_app():
original_stdout_fd=sys.stdout.fileno() # keep reference to original file descriptor of stdouttemp_stdout_fd=os.dup(original_stdout_fd) # store that inside temp_stdout_fd so we can restore stdout laterwithopen("./tmp-stdout.log", "w") asf:
os.dup2(f.fileno(), original_stdout_fd) # make stdout of main application write the tmp-stdout.log fileprocess=subprocess.Popen(["python", "app.py"])
process.wait()
# Here, the textual application is done running, we restore stdoutos.dup2(temp_stdout_fd, original_stdout_fd)
os.close(temp_stdout_fd)
# Restore stdout to be as if we never launched the applicationwithopen("./tmp-stdout.log", "r") asf:
content=f.read()
sys.stdout.write(content)
# Same code for while True loop:
Despite solving the stdout issue, a new problem arose related to screen resizing after importing the readline module, which seems to affect the application's ability to adjust to terminal size changes
The resizing problem
My main application makes an import to readline (without even using it). This somehow, breaks the application's resizing capabilities.
If I add the following import statement to the previous code (without using the imported module):
importreadline
Before resizing:
After rezising down (making screen smaller): I lose the first line
After resizing up (making the screen bigger): The application doesn't resize:
All I did was add an import readline att the start of the previous code, and it breaks the rezising. I don't even use the module, I simply import it
If I remove the import readline, the resizing works:
I can't figure out why this is happening. Please help.
Note: If you have a better idea than launching a threading.Thread and calling subprocess, please do share.
The text was updated successfully, but these errors were encountered:
Textual application having problems resizing when importing
readline
I have developed a Textual-based application that I want to integrate into my main application. I am facing some problems because my main application is calling
import readline
, which is breaking the Textual application's resizing capabilities.Some context
stdout
and writing to files.stdout
to be what it would have been if the textual application was never launched.Solution I came up with and it's problem
Thread
. That thread will make a call tosubprocess.Popen
to run the textual application.stdout
:Fix for the
stdout
problemos.dup2
to switch the file descriptors of the main application to write to a temporary file instead of writing tostdout
.Despite solving the
stdout
issue, a new problem arose related to screen resizing after importing thereadline
module, which seems to affect the application's ability to adjust to terminal size changesThe resizing problem
My main application makes an import to
readline
(without even using it). This somehow, breaks the application's resizing capabilities.If I add the following import statement to the previous code (without using the imported module):
All I did was add an
import readline
att the start of the previous code, and it breaks the rezising. I don't even use the module, I simply import itIf I remove the
import readline
, the resizing works:I can't figure out why this is happening. Please help.
Note: If you have a better idea than launching a
threading.Thread
and callingsubprocess
, please do share.The text was updated successfully, but these errors were encountered: