Marquee¶
A scrolling ticker display for continuous information streams like stock prices or news.
AAPL $185.32 +1.2%
GOOGL $141.80 -0.5%
MSFT $378.91 +0.8%
AMZN $178.25 +2.1%
Basic Usage¶
from pywry import Marquee, TickerItem
items = [
TickerItem(ticker="AAPL", text="AAPL $185.32 +1.2%", class_name="stock-up"),
TickerItem(ticker="GOOGL", text="GOOGL $141.80 -0.5%", class_name="stock-down"),
TickerItem(ticker="MSFT", text="MSFT $378.91 +0.8%", class_name="stock-up"),
]
ticker = Marquee(
text=" ".join(item.build_html() for item in items),
)
Speed Control¶
Direction¶
# Right to left (default)
Marquee(items=[...], direction="left")
# Left to right
Marquee(items=[...], direction="right")
Common Patterns¶
Stock Ticker¶
stocks = [
{"symbol": "AAPL", "price": 185.32, "change": 1.2},
{"symbol": "GOOGL", "price": 141.80, "change": -0.5},
{"symbol": "MSFT", "price": 378.91, "change": 0.8},
{"symbol": "AMZN", "price": 178.25, "change": 2.1},
]
items = [
TickerItem(
ticker=s["symbol"],
text=f"{s['symbol']} ${s['price']:.2f} {'+'if s['change'] > 0 else ''}{s['change']:.1f}%",
class_name="stock-up" if s["change"] > 0 else "stock-down",
)
for s in stocks
]
ticker = Marquee(
component_id="stock-ticker",
text=" ".join(item.build_html() for item in items),
)
toolbar = Toolbar(
position="header",
items=[ticker],
)
Updating Ticker Dynamically¶
from pywry import PyWry, Toolbar, Marquee, TickerItem, Button
app = PyWry()
def on_refresh_prices(data, event_type, label):
# Simulate updated prices
new_prices = [
{"symbol": "AAPL", "price": 186.50, "change": 1.8},
{"symbol": "GOOGL", "price": 142.20, "change": -0.2},
{"symbol": "MSFT", "price": 380.00, "change": 1.1},
]
new_items = [
TickerItem(
ticker=p["symbol"],
text=f"{p['symbol']} ${p['price']:.2f} {'+'if p['change'] > 0 else ''}{p['change']:.1f}%",
class_name="stock-up" if p["change"] > 0 else "stock-down",
)
for p in new_prices
]
app.emit("toolbar:marquee-set-content", {
"id": "stock-ticker",
"text": " ".join(item.build_html() for item in new_items),
}, label)
app.emit("pywry:alert", {"message": "Prices refreshed!", "type": "success"}, label)
app.show(
"<h1>Stock Dashboard</h1>",
toolbars=[
Toolbar(position="header", items=[
Marquee(
component_id="stock-ticker",
text=" ".join(
TickerItem(ticker=s, text=f"{s} --").build_html()
for s in ["AAPL", "GOOGL", "MSFT"]
),
)
]),
Toolbar(position="top", items=[
Button(label="Refresh Prices", event="prices:refresh", variant="primary")
]),
],
callbacks={"prices:refresh": on_refresh_prices},
)
News Ticker¶
headlines = [
"Breaking: Major tech earnings beat expectations",
"Fed signals steady rates through Q2",
"New AI regulations proposed in Congress",
]
news_items = [
TickerItem(ticker=f"news-{i}", text=f"📰 {headline}")
for i, headline in enumerate(headlines)
]
news_ticker = Marquee(
text=" • ".join(item.build_html() for item in news_items),
speed=30, # Slower for readability
)
Metrics Dashboard¶
metric_items = [
TickerItem(ticker="users", text="Users: 12,453 +5%", class_name="stock-up"),
TickerItem(ticker="revenue", text="Revenue: $1.2M +12%", class_name="stock-up"),
TickerItem(ticker="orders", text="Orders: 834 +8%", class_name="stock-up"),
TickerItem(ticker="uptime", text="Uptime: 99.9%"),
]
metrics = Marquee(
text=" ".join(item.build_html() for item in metric_items),
)
Attributes¶
component_id : str | None
Unique identifier for state tracking and dynamic updates (auto-generated if not provided)
label : str | None
Display label (rarely used for marquees)
description : str | None
Tooltip/hover text for accessibility and user guidance
event : str
Event name emitted on click when clickable=True (format: namespace:event-name)
style : str | None
Optional inline CSS
disabled : bool
Whether the marquee is disabled (default: False)
text : str
Text or HTML content to scroll (default: "")
speed : float
Duration in seconds for one scroll cycle — lower is faster (default: 15.0, range: 1.0–300.0)
direction : str
Scroll direction: "left", "right", "up", or "down" (default: "left")
behavior : str
Animation behavior: "scroll", "alternate", "slide", or "static" (default: "scroll")
pause_on_hover : bool
Pause animation when mouse hovers (default: True)
gap : int
Gap in pixels between repeated content (default: 50, range: 0–500)
clickable : bool
Whether clicking the marquee emits an event (default: False)
separator : str
Optional separator between repeated content, e.g. " • " (default: "")
items : list[str] | None
List of content items for static behavior with auto-cycling (default: None)
children : list[ToolbarItem] | None
Nested toolbar items to scroll (alternative to text) (default: None)
Events¶
When clickable=True, emits the event name with payload:
value— text content of the clicked item
Dynamic update event: Use toolbar:marquee-set-content to update items at runtime (see Updating Ticker Dynamically example above).
Styling¶
Customize appearance with CSS:
.pywry-marquee {
background: linear-gradient(to right, #1a1a2e, #16213e);
padding: 8px 0;
}
.pywry-ticker-item {
margin: 0 24px;
}
.pywry-ticker-symbol {
font-weight: bold;
color: #fff;
}
.pywry-ticker-change.positive {
color: #00ff88;
}
.pywry-ticker-change.negative {
color: #ff4444;
}
API Reference¶
For complete parameter documentation, see the Marquee API Reference.