Skip to content

Instantly share code, notes, and snippets.

@paulrobello
Created August 1, 2024 23:10
Show Gist options
  • Save paulrobello/cc9de493940f985e8622b4ca4e9a0597 to your computer and use it in GitHub Desktop.
Save paulrobello/cc9de493940f985e8622b4ca4e9a0597 to your computer and use it in GitHub Desktop.
MRE to test Textual v0.75.0 slowdown
"""MRE to test Textual v0.75.0 slowdown"""
from __future__ import annotations
from dataclasses import dataclass
from textual import on, work
from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.containers import Vertical
from textual.events import Enter, Leave
from textual.message import Message
from textual.screen import Screen
from textual.widgets import (
ListView,
ListItem,
Static,
Header,
Footer,
TabbedContent,
TabPane,
)
@dataclass
class LoadItems(Message):
"""Load items into the list view"""
class MyListItem(ListItem):
"""Basic 3 line list item with some styling"""
DEFAULT_CSS = """
MyListItem {
padding: 1;
background: $background;
border: solid $accent;
border-title-color: $primary;
}
"""
def __init__(self, i: int) -> None:
"""Initialize the list item with a number"""
super().__init__()
self.i = i
self.border_title = f"Woot {self.i}"
def compose(self) -> ComposeResult:
"""Compose the list item"""
with Vertical():
yield Static(f"Woot Line1 - {self.i}")
yield Static(f"Woot Line2 - {self.i}")
yield Static(f"Woot Line3 - {self.i}")
# use the on_enter and on leave to stop the bubble and restore performance
# @on(Enter)
# def on_enter(self, event: Enter) -> None:
# """Stop the bubble"""
# event.stop()
#
# @on(Leave)
# def on_leave(self, event: Leave) -> None:
# """Stop the bubble"""
# event.stop()
class MainScreen(Screen[None]):
"""Main screen with 2 tabs each with a 100 item list view"""
BINDINGS = [
Binding("ctrl+c", "quit", "Quit", show=True, priority=True),
Binding("ctrl+backslash", "command_palette", show=True, priority=True),
]
items1: list[MyListItem]
items2: list[MyListItem]
tabbed_content: TabbedContent
def __init__(self) -> None:
"""Initialise the screen list items but dont add them yet."""
super().__init__()
self.items1 = []
self.items2 = []
for i in range(100):
self.items1.append(MyListItem(i=i))
self.items2.append(MyListItem(i=i + 100))
def compose(self) -> ComposeResult:
"""Compose the screen"""
yield Header()
yield Footer()
with TabbedContent(id="tabbed_content") as tc:
self.tabbed_content = tc
with TabPane("List 1", id="list1"):
yield ListView(id="lv1")
with TabPane("List 2", id="list2"):
yield ListView(id="lv2")
@on(LoadItems)
def add_items(self, event: LoadItems) -> None:
"""Handle the load items message."""
event.stop()
lv: ListView = self.query_one("#lv1", ListView)
lv.loading = True
lv.clear()
lv.extend(self.items1)
lv.loading = False
lv = self.query_one("#lv2", ListView)
lv.loading = True
lv.clear()
lv.extend(self.items2)
lv.loading = False
class MyApp(App[None]):
"""App to test list view slow down"""
def __init__(self) -> None:
"""Initialise the app."""
super().__init__()
self.main_screen = MainScreen()
async def on_mount(self) -> None:
"""App waits 1 second then sends message to add items to the list views."""
await self.push_screen(self.main_screen)
self.set_timer(1, self.add_items)
def add_items(self) -> None:
"""Send message to add items to the list views."""
# self.do_work() # sending message from worker thread does not change performance
self.main_screen.post_message(LoadItems())
@work(group="the_workers", thread=True)
async def do_work(self) -> None:
"""Send message from thread to add items to the list views."""
self.main_screen.post_message(LoadItems())
if __name__ == "__main__":
MyApp().run()
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
attrs = "*"
certifi = "*"
requests-file = "*"
#textual = { version = "==0.74.0", extras = ["syntax"] }
textual = { version = "==0.75.0", extras = ["syntax"] }
asyncio = "*"
rich = "*"
[dev-packages]
mypy = "*"
build = "*"
typing-extensions = "*"
types-simplejson = "*"
black = "*"
pylint = "*"
textual-dev = "*"
[requires]
python_version = "3.11"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment