A minimal threaded wrapper for Python curses
Project description
Cursers
A minimal threaded wrapper for Python curses that simplifies terminal user interface development with built-in threading support and lifecycle management.
Features
- Simple context manager for curses applications
- Built-in update loop with configurable FPS
- Lifecycle hooks for application logic
- Threaded version for running updates in separate thread
- Text drawing utilities with styling support
Installation
pip install cursers
Quick Start
Basic App
import cursers
class MyApp(cursers.App):
# Called when entering the application context
def on_enter(self):
self.draw_text(0, 0, "Hello, World!", bold=True)
# Called each frame with the current key input
def on_update(self, key):
if key == 27: # ESC key
self.exit()
# Run the application
with MyApp() as app:
while app.is_running():
app.update()
Threaded App
import cursers
import time
class MyThreadedApp(cursers.ThreadedApp):
def on_enter(self):
self.draw_text(0, 0, "Running in background thread!")
def on_update(self, key):
if key == 27: # ESC key
self.exit()
# Run in background thread
with MyThreadedApp() as app:
while app.is_running():
time.sleep(0.1) # Do other work
API Reference
App Class
The main application class that provides a context manager for curses applications.
Constructor
App(fps=30)
fps: Target frames per second (default: 30)
Methods
is_running(): ReturnsTrueif the application is runningupdate(): Updates the application state and handles input (call in main loop)exit(): Signals the application to exitdraw_text(y, x, text, bold=False, underline=False): Draw text at position
Lifecycle Hooks
Override these methods in your subclass:
on_enter(): Called when entering the contexton_update(key): Called every frame with key input (-1 if no key pressed)on_exit(): Called when exiting the context
ThreadedApp Class
Extends App to run the update loop in a separate thread.
class MyThreadedApp(cursers.ThreadedApp):
def on_update(self, key):
# Handle input and drawing
pass
with MyThreadedApp() as app:
# Update loop runs automatically in background thread
while app.is_running():
# Main thread is free for other tasks
time.sleep(0.1)
Thread Class
Basic threading context manager for custom threading needs.
class MyThread(cursers.Thread):
def run(self):
# Your thread code here
pass
with MyThread() as thread:
# Thread runs automatically
pass
Examples
Check out the examples/ directory for complete working examples:
examples/move_control.py- Basic movement control with keyboard inputexamples/move_control_gravity.py- Threaded application with gravity simulation
Development
Setup
# Clone the repository
git clone https://github.com/threeal/cursers.git
cd cursers
# Install development dependencies
uv sync
# Install Git hooks
uv run lefthook install
Code Quality
# Format code
dprint fmt
# Run linter
uv run ruff check --fix
License
This project is licensed under the terms of the MIT License.
Copyright © 2025 Alfi Maulana
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cursers-0.1.0.tar.gz.
File metadata
- Download URL: cursers-0.1.0.tar.gz
- Upload date:
- Size: 4.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6682c9c8c38b0a45f8f2a3a624cd63e7dce71a08cfa36b4bceae6c8b76dd0294
|
|
| MD5 |
62a4e90f3a1955981d93df9ac67295ee
|
|
| BLAKE2b-256 |
fba0ec548c5308ae43c39460005e90f104ab262a05d0a22a57c36be6dc143bb8
|
File details
Details for the file cursers-0.1.0-py3-none-any.whl.
File metadata
- Download URL: cursers-0.1.0-py3-none-any.whl
- Upload date:
- Size: 5.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f0a14236891664b3c42ac5fd1e825cc457e10f13baaced59acb73e04d4e01502
|
|
| MD5 |
15e6926087f8e26eaf4306bbd659f2b5
|
|
| BLAKE2b-256 |
6b9792cd79c4391f0a19e89a7c66a0de004fc5e7963e77e5851b335a8322a619
|