In Textual, I have an app which has 3 modes. However I want to switch the mode inside a screen based on user input. How do I accomplish that? App.py :
class DemoApp(App[None]):
MODES = {
"profile": ProfileScreen,
"chat": ChatScreen,
"help": HelpScreen,
}
def on_mount(self) -> None:
"""On running"""
LOGGER.info("Starting")
self.switch_mode("chat")
class ChatScreen(Screen):
def compose(self) -> ComposeResult:
yield Button(label="Profile", variant="success", id="change_profile")
async def on_button_pressed(self) -> None:
await self.process()
async def process():
switch_mode("profile") # How do I do this?
I searched all over google and read the docs. But I still couldn't find a solution.
You can get the running App
instance through the app
property, so just:
async def process(self):
self.app.switch_mode("profile")
Note that you had forgotten the self
argument in the process
instance method.
A reproducible example:
from textual.app import App, ComposeResult
from textual.screen import Screen
from textual.widgets import Button
class ChatScreen(Screen):
def compose(self) -> ComposeResult:
yield Button(label="Profile", variant="success", id="change_profile")
async def on_button_pressed(self) -> None:
self.app.switch_mode("profile")
class ProfileScreen(Screen):
def compose(self) -> ComposeResult:
yield Button(label="Help", variant="success", id="change_profile")
async def on_button_pressed(self) -> None:
self.app.switch_mode("help")
class HelpScreen(Screen):
def compose(self) -> ComposeResult:
yield Button(label="Chat", variant="success", id="change_profile")
async def on_button_pressed(self) -> None:
self.app.switch_mode("chat")
class DemoApp(App[None]):
MODES = {
"profile": ProfileScreen,
"chat": ChatScreen,
"help": HelpScreen,
}
def on_mount(self) -> None:
"""On running"""
# LOGGER.info("Starting")
self.switch_mode("chat")
if __name__ == "__main__":
app = DemoApp()
app.run()