Switch mode from inside a screen in Textual library - Python

33 views Asked by At

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.

1

There are 1 answers

0
FJSevilla On BEST ANSWER

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()