Unexpected behavior when changing button color using a worker #5228
-
I'm trying to create a web worker that updates the button color temporarily (for 300ms) and then changes it back to the default color. However, when I use a worker to perform this task, the UI remains unresponsive, and the color change only occurs after the worker finishes processing, rather than immediately updating the color as expected. Expected behavior: The button color should change immediately when the worker is triggered and revert back to the default color after 300ms, without blocking UI updates or causing unresponsiveness. Actual behavior: The UI remains unresponsive until the worker completes its task, and the color change happens only after the worker finishes. How can I achieve this? Example application: from textual import on, work
from textual.app import App, ComposeResult
from textual.containers import Container
from textual.widgets import Button
from time import sleep
class UserInterface(App):
"""A 3x3 grid of clickable buttons."""
CSS_PATH = "style.tcss"
def compose(self) -> ComposeResult:
"""Add our 3x3 grid of buttons."""
with Container(id="grid"):
for index in range(9):
button_id = f"button-{index}"
button_label = f"{index}"
yield Button(button_label, id=button_id)
@on(Button.Pressed)
async def on_button_pressed(self, event: Button.Pressed) -> None:
"""Pressed a number."""
self.highlight(event.button.id)
# ============================================================
def toggle_button_highlight(self, button_id):
button = self.query_one(f"#{button_id}")
if button.variant == "primary":
button.variant = "default"
else:
button.variant = "primary"
@work
async def highlight(self, button_id):
"""Highlights a button, waits and removes the highlight."""
self.toggle_button_highlight(button_id)
sleep(0.3)
self.toggle_button_highlight(button_id)
if __name__ == "__main__":
UserInterface().run(inline=True) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
Beta Was this translation helpful? Give feedback.
time.sleep
isn't asynchronous, which means Textual can't do anything for 0.3 seconds. You could useasyncio.sleep
, but there are better options. Consider using set_timer, rather than a worker.