Quick Start
This guide will get you building your first Wijjit application in just a few minutes.
Hello World
Let’s start with the simplest possible Wijjit app:
from wijjit import Wijjit, render_template_string
app = Wijjit()
@app.view("main", default=True)
def main_view():
return render_template_string("Hello, World! Press 'q' to quit.")
@app.on_key("q")
def quit_app(event):
app.quit()
if __name__ == "__main__":
app.run()
Save this as hello.py and run it:
python hello.py
You should see “Hello, World!” displayed in your terminal. Press q to quit.
A template that is nothing but text needs no tags – Wijjit wraps it in a text
element for you, so it renders exactly as if you had written
{% text %}...{% endtext %}. Reach for the explicit tag when you want to
control the line – align, wrap, or a class to style it; the next
section wraps this one in a {% frame %} instead.
Understanding the Code
Let’s break down what’s happening:
Import Wijjit:
from wijjit import Wijjitimports the main app classCreate app:
app = Wijjit()creates a new Wijjit applicationDefine view:
@app.view("main", default=True)decorates a function that defines the main viewReturn template: The view function returns
render_template_string(...)with the template source containing the UIHandle a key:
@app.on_key("q")registers a handler that quits whenqis pressedRun app:
app.run()starts the event loop
Adding a Frame
Let’s add a border around our text using a frame:
from wijjit import Wijjit, render_template_string
app = Wijjit()
@app.view("main", default=True)
def main_view():
return render_template_string("""
{% frame title="Welcome" border="rounded" width=50 height=10 %}
Hello, World!
This is a Wijjit TUI application.
Press 'q' to quit.
{% endframe %}
""")
@app.on_key("q")
def quit_app(event):
app.quit()
if __name__ == "__main__":
app.run()
Now the text is displayed inside a rounded box with a title!
Adding State and Input
Let’s create an interactive app with a text input and button:
from wijjit import Wijjit, render_template_string
app = Wijjit(initial_state={
'name': '',
'greeting': 'Please enter your name'
})
@app.view("main", default=True)
def main_view():
return render_template_string("""
{% frame title="Greeting App" border="single" width=60 height=12 %}
{% vstack spacing=1 padding=1 %}
{{ state.greeting }}
{% vstack spacing=0 %}
Your name:
{% textinput id="name" placeholder="Enter your name" width=30 autofocus=True %}{% endtextinput %}
{% endvstack %}
{% hstack spacing=2 %}
{% button action="greet" %}Greet Me{% endbutton %}
{% button action="quit" %}Quit{% endbutton %}
{% endhstack %}
{% endvstack %}
{% endframe %}
""")
@app.on_action("greet")
def handle_greet(event):
name = app.state.get('name', '').strip()
if name:
app.state['greeting'] = f"Hello, {name}! Nice to meet you!"
else:
app.state['greeting'] = "Please enter your name first"
@app.on_action("quit")
def handle_quit(event):
app.quit()
if __name__ == '__main__':
app.run()
Key Concepts Demonstrated
State Management:
initial_statesets up reactive stateTemplates: Jinja2 templates with custom tags (
frame,vstack,textinput,button)State Binding: The
textinputwithid="name"automatically binds toapp.state['name']Actions: Buttons trigger actions that are handled by
@app.on_action()decoratorsReactivity: Changing
app.state['greeting']automatically re-renders the UIInitial focus:
autofocus=Trueputs the cursor in the name field on start. Without it an app begins with nothing focused and the user must press Tab before typing does anything - see Initial focus: the autofocus attribute
Login Form Example
Here’s a complete login form with validation:
from wijjit import Wijjit, render_template_string
app = Wijjit(initial_state={
'username': '',
'password': '',
'status': 'Please enter your credentials',
})
@app.view("login", default=True)
def login_view():
return render_template_string("""
{% frame title="Login" border="single" width=50 height=15 %}
{% vstack spacing=1 padding=1 %}
{{ state.status }}
{% vstack spacing=0 %}
Username:
{% textinput id="username" placeholder="Enter username" width=30 autofocus=True %}{% endtextinput %}
{% endvstack %}
{% vstack spacing=0 %}
Password:
{% textinput id="password" placeholder="Enter password" width=30 action="login" %}{% endtextinput %}
{% endvstack %}
{% hstack spacing=2 %}
{% button action="login" %}Login{% endbutton %}
{% button action="clear" %}Clear{% endbutton %}
{% button action="quit" %}Quit{% endbutton %}
{% endhstack %}
{% endvstack %}
{% endframe %}
""")
@app.on_action("login")
def handle_login(event):
username = app.state.get('username', '')
password = app.state.get('password', '')
if not username:
app.state['status'] = 'Error: Username is required'
elif not password:
app.state['status'] = 'Error: Password is required'
elif username == 'admin' and password == 'password':
app.state['status'] = f'Success! Welcome, {username}!'
else:
app.state['status'] = 'Error: Invalid credentials'
app.state['password'] = '' # Clear password on failed login
@app.on_action("clear")
def handle_clear(event):
app.state['username'] = ''
app.state['password'] = ''
app.state['status'] = 'Form cleared'
@app.on_action("quit")
def handle_quit(event):
app.quit()
if __name__ == '__main__':
app.run()
Try logging in with:
* Username: admin
* Password: password
Features Shown
Form validation
Error messages
Multiple buttons with different actions
Clearing form data
Initial focus via
autofocus=Trueon the username field, then Tab/Shift+Tab to move between fieldsEnter key in password field triggers login action
Common Patterns
Keyboard Shortcuts
Add custom keyboard shortcuts:
@app.on_key("ctrl+s")
def save(event):
# Save logic here
pass
@app.on_key("ctrl+q")
def quit_app(event):
app.quit()
Working with Lists
Display and interact with lists of data:
app = Wijjit(initial_state={
'items': ['Apple', 'Banana', 'Cherry'],
'selected': None
})
@app.view("main", default=True)
def main_view():
items_text = '\n'.join(f"- {item}" for item in app.state['items'])
return render_template_string("""
{% frame title="Items" %}
{{ items_text }}
{% endframe %}
""", items_text=items_text)
Next Steps
Now that you’ve built your first Wijjit apps, you can:
Follow the Tutorial: Persistent Todo App to build a complete todo list application
Learn about Core Concepts in depth
Explore the Components available in Wijjit
Check out the Examples for more complex applications
Where to Go From Here
Tutorial: Tutorial: Persistent Todo App - Build a complete todo list app
User Guide: Core Concepts - Deep dive into Wijjit concepts
Examples: 74 runnable scripts across
examples/basic,examples/widgets,examples/advanced,examples/styling, andexamples/appsAPI Reference: Core API - Detailed API documentation