mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
more general app
This commit is contained in:
@@ -91,7 +91,7 @@ class Success(Widget):
|
|||||||
return Text("This is a success message", justify="center")
|
return Text("This is a success message", justify="center")
|
||||||
|
|
||||||
|
|
||||||
class BasicApp(App):
|
class BasicApp(App, css_path="basic.css"):
|
||||||
"""A basic app demonstrating CSS"""
|
"""A basic app demonstrating CSS"""
|
||||||
|
|
||||||
def on_load(self):
|
def on_load(self):
|
||||||
@@ -158,7 +158,7 @@ class BasicApp(App):
|
|||||||
tweet_body.refresh(layout=True)
|
tweet_body.refresh(layout=True)
|
||||||
|
|
||||||
|
|
||||||
app = BasicApp(css_path="basic.css")
|
app = BasicApp()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app.run()
|
app.run()
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class TextWidget(Widget):
|
|||||||
return TEXT
|
return TEXT
|
||||||
|
|
||||||
|
|
||||||
class AutoApp(App):
|
class AutoApp(App, css_path="nest.css"):
|
||||||
def on_mount(self) -> None:
|
def on_mount(self) -> None:
|
||||||
self.bind("t", "tree")
|
self.bind("t", "tree")
|
||||||
|
|
||||||
@@ -30,9 +30,3 @@ class AutoApp(App):
|
|||||||
|
|
||||||
def action_tree(self):
|
def action_tree(self):
|
||||||
self.log(self.screen.tree)
|
self.log(self.screen.tree)
|
||||||
|
|
||||||
|
|
||||||
app = AutoApp(css_path="nest.css")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
app.run()
|
|
||||||
|
|||||||
@@ -109,6 +109,8 @@ class App(Generic[ReturnType], DOMNode):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
CSS_PATH: str | None = None
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
driver_class: Type[Driver] | None = None,
|
driver_class: Type[Driver] | None = None,
|
||||||
@@ -188,8 +190,7 @@ class App(Generic[ReturnType], DOMNode):
|
|||||||
|
|
||||||
self.stylesheet = Stylesheet(variables=self.get_css_variables())
|
self.stylesheet = Stylesheet(variables=self.get_css_variables())
|
||||||
self._require_styles_update = False
|
self._require_styles_update = False
|
||||||
|
self.css_path = css_path or self.CSS_PATH
|
||||||
self.css_path = css_path
|
|
||||||
|
|
||||||
self.registry: set[MessagePump] = set()
|
self.registry: set[MessagePump] = set()
|
||||||
self.devtools = DevtoolsClient()
|
self.devtools = DevtoolsClient()
|
||||||
@@ -203,6 +204,10 @@ class App(Generic[ReturnType], DOMNode):
|
|||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
def __init_subclass__(cls, css_path: str | None = None) -> None:
|
||||||
|
super().__init_subclass__()
|
||||||
|
cls.CSS_PATH = css_path
|
||||||
|
|
||||||
title: Reactive[str] = Reactive("Textual")
|
title: Reactive[str] = Reactive("Textual")
|
||||||
sub_title: Reactive[str] = Reactive("")
|
sub_title: Reactive[str] = Reactive("")
|
||||||
background: Reactive[str] = Reactive("black")
|
background: Reactive[str] = Reactive("black")
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ def import_app(import_name: str) -> App:
|
|||||||
from textual.app import App
|
from textual.app import App
|
||||||
|
|
||||||
lib, _colon, name = import_name.partition(":")
|
lib, _colon, name = import_name.partition(":")
|
||||||
name = name or "app"
|
|
||||||
|
|
||||||
if lib.endswith(".py"):
|
if lib.endswith(".py"):
|
||||||
# We're assuming the user wants to load a .py file
|
# We're assuming the user wants to load a .py file
|
||||||
@@ -60,10 +59,41 @@ def import_app(import_name: str) -> App:
|
|||||||
global_vars: dict[str, object] = {}
|
global_vars: dict[str, object] = {}
|
||||||
exec(py_code, global_vars)
|
exec(py_code, global_vars)
|
||||||
|
|
||||||
try:
|
if name:
|
||||||
app = global_vars[name]
|
# User has give a name, use that
|
||||||
except KeyError:
|
try:
|
||||||
raise AppFail(f"App {name!r} not found in {lib!r}")
|
app = global_vars[name]
|
||||||
|
except KeyError:
|
||||||
|
raise AppFail(f"App {name!r} not found in {lib!r}")
|
||||||
|
else:
|
||||||
|
# User has not given a name
|
||||||
|
if "app" in global_vars:
|
||||||
|
# App exists, lets use that
|
||||||
|
try:
|
||||||
|
app = global_vars[name]
|
||||||
|
except KeyError:
|
||||||
|
raise AppFail(f"App {name!r} not found in {lib!r}")
|
||||||
|
else:
|
||||||
|
# Find a App class or instance that is *not* the base class
|
||||||
|
apps = [
|
||||||
|
value
|
||||||
|
for key, value in global_vars.items()
|
||||||
|
if (
|
||||||
|
isinstance(value, App)
|
||||||
|
or (inspect.isclass(value) and issubclass(value, App))
|
||||||
|
and value is not App
|
||||||
|
)
|
||||||
|
]
|
||||||
|
if not apps:
|
||||||
|
raise AppFail(
|
||||||
|
f'Unable to find app in {lib!r}, try specifying app with "foo.py:app"'
|
||||||
|
)
|
||||||
|
if len(apps) > 1:
|
||||||
|
raise AppFail(
|
||||||
|
f'Multiple apps found {lib!r}, try specifying app with "foo.py:app"'
|
||||||
|
)
|
||||||
|
app = apps[0]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Assuming the user wants to import the file
|
# Assuming the user wants to import the file
|
||||||
sys.path.append("")
|
sys.path.append("")
|
||||||
@@ -78,7 +108,7 @@ def import_app(import_name: str) -> App:
|
|||||||
raise AppFail(f"Unable to find {name!r} in {module!r}")
|
raise AppFail(f"Unable to find {name!r} in {module!r}")
|
||||||
|
|
||||||
if inspect.isclass(app) and issubclass(app, App):
|
if inspect.isclass(app) and issubclass(app, App):
|
||||||
app = App()
|
app = app()
|
||||||
|
|
||||||
return cast(App, app)
|
return cast(App, app)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user