Close Menu
    Facebook X (Twitter) Instagram
    Articles Stock
    • Home
    • Technology
    • AI
    • Pages
      • About us
      • Contact us
      • Disclaimer For Articles Stock
      • Privacy Policy
      • Terms and Conditions
    Facebook X (Twitter) Instagram
    Articles Stock
    AI

    Find out how to Design a Totally Interactive, Reactive, and Dynamic Terminal-Primarily based Knowledge Dashboard Utilizing Textual?

    Naveed AhmadBy Naveed Ahmad15/11/2025No Comments6 Mins Read
    blog banner 46


    On this tutorial, we construct a complicated interactive dashboard utilizing Textual, and we discover how terminal-first UI frameworks can really feel as expressive and dynamic as trendy net dashboards. As we write and run every snippet, we actively assemble the interface piece by piece, widgets, layouts, reactive state, and occasion flows, so we are able to see how Textual behaves like a stay UI engine proper inside Google Colab. By the tip, we discover how naturally we are able to mix tables, bushes, kinds, and progress indicators right into a cohesive software that feels quick, clear, and responsive. Try the FULL CODES here.

    !pip set up textual textual-web nest-asyncio
    
    
    from textual.app import App, ComposeResult
    from textual.containers import Container, Horizontal, Vertical
    from textual.widgets import (
       Header, Footer, Button, DataTable, Static, Enter,
       Label, ProgressBar, Tree, Choose
    )
    from textual.reactive import reactive
    from textual import on
    from datetime import datetime
    import random
    
    
    class StatsCard(Static):
       worth = reactive(0)
      
       def __init__(self, title: str, *args, **kwargs):
           tremendous().__init__(*args, **kwargs)
           self.title = title
          
       def compose(self) -> ComposeResult:
           yield Label(self.title)
           yield Label(str(self.worth), id="stat-value")
      
       def watch_value(self, new_value: int) -> None:
           if self.is_mounted:
               strive:
                   self.query_one("#stat-value", Label).replace(str(new_value))
               besides Exception:
                   cross

    We arrange the surroundings and import all the mandatory elements to construct our Textual software. As we outline the StatsCard widget, we set up a reusable part that reacts to modifications in worth and updates itself routinely. We start to see how Textual’s reactive system lets us create dynamic UI parts with minimal effort. Try the FULL CODES here.

    class DataDashboard(App):
       CSS = """
       Display screen { background: $floor; }
       #main-container { peak: 100%; padding: 1; }
       #stats-row { peak: auto; margin-bottom: 1; }
       StatsCard { border: strong $main; peak: 5; padding: 1; margin-right: 1; width: 1fr; }
       #stat-value { text-style: daring; shade: $accent; content-align: middle center; }
       #control-panel { peak: 12; border: strong $secondary; padding: 1; margin-bottom: 1; }
       #data-section { peak: 1fr; }
       #left-panel { width: 30; border: strong $secondary; padding: 1; margin-right: 1; }
       DataTable { peak: 100%; border: strong $main; }
       Enter { margin: 1 0; }
       Button { margin: 1 1 1 0; }
       ProgressBar { margin: 1 0; }
       """
      
       BINDINGS = [
           ("d", "toggle_dark", "Toggle Dark Mode"),
           ("q", "quit", "Quit"),
           ("a", "add_row", "Add Row"),
           ("c", "clear_table", "Clear Table"),
       ]
      
       total_rows = reactive(0)
       total_sales = reactive(0)
       avg_rating = reactive(0.0)

    We outline the DataDashboard class and configure international types, key bindings, and reactive attributes. We resolve how the app ought to look and behave proper from the highest, giving us full management over themes and interactivity. This construction helps us create a cultured dashboard with out writing any HTML or JS. Try the FULL CODES here.

      def compose(self) -> ComposeResult:
           yield Header(show_clock=True)
          
           with Container(id="main-container"):
               with Horizontal(id="stats-row"):
                   yield StatsCard("Whole Rows", id="card-rows")
                   yield StatsCard("Whole Gross sales", id="card-sales")
                   yield StatsCard("Avg Score", id="card-rating")
              
               with Vertical(id="control-panel"):
                   yield Enter(placeholder="Product Identify", id="input-name")
                   yield Choose(
                       [("Electronics", "electronics"),
                        ("Books", "books"),
                        ("Clothing", "clothing")],
                       immediate="Choose Class",
                       id="select-category"
                   )
                   with Horizontal():
                       yield Button("Add Row", variant="main", id="btn-add")
                       yield Button("Clear Desk", variant="warning", id="btn-clear")
                       yield Button("Generate Knowledge", variant="success", id="btn-generate")
                   yield ProgressBar(complete=100, id="progress")
              
               with Horizontal(id="data-section"):
                   with Container(id="left-panel"):
                       yield Label("Navigation")
                       tree = Tree("Dashboard")
                       tree.root.develop()
                       merchandise = tree.root.add("Merchandise", develop=True)
                       merchandise.add_leaf("Electronics")
                       merchandise.add_leaf("Books")
                       merchandise.add_leaf("Clothes")
                       tree.root.add_leaf("Experiences")
                       tree.root.add_leaf("Settings")
                       yield tree
                  
                   yield DataTable(id="data-table")
          
           yield Footer()

    We compose your entire UI format, arranging containers, playing cards, type inputs, buttons, a navigation tree, and a knowledge desk. As we construction these elements, we watch the interface take form precisely the way in which we envision it. This snippet lets us design the visible skeleton of the dashboard in a clear, declarative method. Try the FULL CODES here.

     def on_mount(self) -> None:
           desk = self.query_one(DataTable)
           desk.add_columns("ID", "Product", "Class", "Value", "Gross sales", "Score")
           desk.cursor_type = "row"
           self.generate_sample_data(5)
           self.set_interval(0.1, self.update_progress)
      
       def generate_sample_data(self, rely: int = 5) -> None:
           desk = self.query_one(DataTable)
           classes = ["Electronics", "Books", "Clothing"]
           merchandise = {
               "Electronics": ["Laptop", "Phone", "Tablet", "Headphones"],
               "Books": ["Novel", "Textbook", "Magazine", "Comic"],
               "Clothes": ["Shirt", "Pants", "Jacket", "Shoes"]
           }
          
           for _ in vary(rely):
               class = random.alternative(classes)
               product = random.alternative(productsArtificial Intelligence)
               row_id = self.total_rows + 1
               value = spherical(random.uniform(10, 500), 2)
               gross sales = random.randint(1, 100)
               score = spherical(random.uniform(1, 5), 1)
              
               desk.add_row(
                   str(row_id),
                   product,
                   class,
                   f"${value}",
                   str(gross sales),
                   str(score)
               )
              
               self.total_rows += 1
               self.total_sales += gross sales
          
           self.update_stats()
      
       def update_stats(self) -> None:
           self.query_one("#card-rows", StatsCard).worth = self.total_rows
           self.query_one("#card-sales", StatsCard).worth = self.total_sales
          
           if self.total_rows > 0:
               desk = self.query_one(DataTable)
               total_rating = sum(float(row[5]) for row in desk.rows)
               self.avg_rating = spherical(total_rating / self.total_rows, 2)
               self.query_one("#card-rating", StatsCard).worth = self.avg_rating
      
       def update_progress(self) -> None:
           progress = self.query_one(ProgressBar)
           progress.advance(1)
           if progress.progress >= 100:
               progress.progress = 0

    We implement all of the logic for producing information, computing statistics, animating progress, and updating playing cards. We see how rapidly we are able to bind backend logic to frontend elements utilizing Textual’s reactive mannequin. This step makes the dashboard really feel alive as numbers replace immediately and progress bars animate easily. Try the FULL CODES here.

     @on(Button.Pressed, "#btn-add")
       def handle_add_button(self) -> None:
           name_input = self.query_one("#input-name", Enter)
           class = self.query_one("#select-category", Choose).worth
          
           if name_input.worth and class:
               desk = self.query_one(DataTable)
               row_id = self.total_rows + 1
               value = spherical(random.uniform(10, 500), 2)
               gross sales = random.randint(1, 100)
               score = spherical(random.uniform(1, 5), 1)
              
               desk.add_row(
                   str(row_id),
                   name_input.worth,
                   str(class),
                   f"${value}",
                   str(gross sales),
                   str(score)
               )
              
               self.total_rows += 1
               self.total_sales += gross sales
               self.update_stats()
               name_input.worth = ""
      
       @on(Button.Pressed, "#btn-clear")
       def handle_clear_button(self) -> None:
           desk = self.query_one(DataTable)
           desk.clear()
           self.total_rows = 0
           self.total_sales = 0
           self.avg_rating = 0
           self.update_stats()
      
       @on(Button.Pressed, "#btn-generate")
       def handle_generate_button(self) -> None:
           self.generate_sample_data(10)
      
       def action_toggle_dark(self) -> None:
           self.darkish = not self.darkish
      
       def action_add_row(self) -> None:
           self.handle_add_button()
      
       def action_clear_table(self) -> None:
           self.handle_clear_button()
    
    
    
    
    if __name__ == "__main__":
       import nest_asyncio
       nest_asyncio.apply()
       app = DataDashboard()
       app.run()

    We join UI occasions to backend actions utilizing button handlers, keyboard shortcuts, and app-level capabilities. As we run the app, we work together with a completely practical dashboard that responds immediately to each click on and command. This snippet completes the applying and demonstrates how simply Textual permits us to construct dynamic, state-driven UIs.

    In conclusion, we see the entire dashboard come collectively in a completely practical, interactive type that runs instantly from a pocket book surroundings. We expertise firsthand how Textual lets us design terminal UIs with the construction and really feel of net apps, whereas staying totally in Python. This tutorial leaves us assured that we are able to lengthen this basis, even including charts, API feeds, and multi-page navigation, as we proceed to experiment with Textual’s trendy reactive UI capabilities.


    Try the FULL CODES here. Be at liberty to take a look at our GitHub Page for Tutorials, Codes and Notebooks. Additionally, be happy to comply with us on Twitter and don’t neglect to affix our 100k+ ML SubReddit and Subscribe to our Newsletter. Wait! are you on telegram? now you can join us on telegram as well.


    Asif Razzaq is the CEO of Marktechpost Media Inc.. As a visionary entrepreneur and engineer, Asif is dedicated to harnessing the potential of Synthetic Intelligence for social good. His most up-to-date endeavor is the launch of an Synthetic Intelligence Media Platform, Marktechpost, which stands out for its in-depth protection of machine studying and deep studying information that’s each technically sound and simply comprehensible by a large viewers. The platform boasts of over 2 million month-to-month views, illustrating its recognition amongst audiences.

    🙌 Follow MARKTECHPOST: Add us as a preferred source on Google.



    Source link

    Naveed Ahmad

    Related Posts

    Former Tesla product supervisor desires to make luxurious items unimaginable to pretend, beginning with a chip

    10/02/2026

    Alibaba Open-Sources Zvec: An Embedded Vector Database Bringing SQLite-like Simplicity and Excessive-Efficiency On-Gadget RAG to Edge Functions

    10/02/2026

    YouTubers aren’t counting on advert income anymore — this is how some are diversifying

    10/02/2026
    Leave A Reply Cancel Reply

    Categories
    • AI
    Recent Comments
      Facebook X (Twitter) Instagram Pinterest
      © 2026 ThemeSphere. Designed by ThemeSphere.

      Type above and press Enter to search. Press Esc to cancel.