Delarative Tcl/Tk
Project description
Tkintergalactic
Declarative Tcl/Tk UI library for Python.
- Somewhat React-like (there is effectively a Tk VDOM).
- Well typed.
- Maps very closely to the underlying Tcl/Tk for ease of debugging.
- Zero dependency.
- On mac sometimes you have to start by wiggling the window.
- Small enough to understand how it works.
- In an incomplete state - much functionality missing.
Hello World
After pip install tkintergalactic, just run:
import tkintergalactic as tk
counter = 0
@tk.command()
def inc_counter() -> None:
global counter
counter += 1
tk.Window(
app=lambda: tk.Frame(
tk.Button(text="Hello World!", onbuttonrelease=inc_counter),
tk.Text(content=f"Button clicked {counter} times"),
),
).run()
TODO list
from dataclasses import dataclass, field
import tkintergalactic as tk
@dataclass
class Task:
description: str
complete: bool = False
@dataclass
class State:
tasks: list[Task] = field(default_factory=list)
new_task_description: str = ""
state = State()
@tk.command()
def add_task() -> None:
state.tasks.append(Task(state.new_task_description))
state.new_task_description = ""
@tk.command()
def delete_task(i: int) -> None:
state.tasks.pop(i)
@tk.command()
def toggle_class_complete(i: int) -> None:
state.tasks[i].complete = not state.tasks[i].complete
@tk.command(with_event=True)
def set_new_task_description(e: tk.EventKeyRelease) -> None:
state.new_task_description = e.value
tk.Window(
title="TODO List",
h=600,
w=500,
app=lambda: tk.Frame(
tk.Frame(
[
tk.Frame(
tk.Entry(
value=task.description,
side="left",
font=tk.Font(styles=["overstrike"]) if task.complete else tk.Font(),
expand=True,
),
tk.Button(
text="✗" if task.complete else "✔",
onbuttonrelease=toggle_class_complete.partial(i=i),
),
tk.Button(text="Delete", onbuttonrelease=delete_task.partial(i=i), side="right"),
fill="x",
expand=True,
)
for i, task in enumerate(state.tasks)
],
fill="x",
expand=True,
),
tk.Frame(
tk.Entry(
value=state.new_task_description,
onkeyrelease=set_new_task_description,
side="left",
expand=True,
),
tk.Button(
text="New Task",
onbuttonrelease=add_task,
),
fill="x",
),
tk.Text(
content=f"Total number of tasks: {len(state.tasks)}\nComplete: {sum(t.complete for t in state.tasks)}",
),
),
).run()
Packer example
The packer is the main way of arranging Widgets.
import tkintergalactic as tk
tk.Window(
title="Packer",
w=200,
h=300,
app=lambda: tk.Frame(
tk.Button(text="t", side="top", fill="x"),
tk.Button(text="b", side="bottom", fill="x"),
tk.Button(text="l", side="left"),
tk.Button(text="r", side="right"),
tk.Text(content="mid", expand=True, fill="both"),
fill="both",
expand=True,
),
).run()
Further work
Functionality
The majority of the functionality in the Tk Docs is still not implemented, most of it is just a case of padding out existing functionality in widgets.py, however there are some complicated text buffer bits that would take a lot more work.
Diffing
- The diffing algorithm could be made more efficient - see eg. the referenced alogrithms in the
mithrilcode. - Could allow passing optional
ids to widgets to make diffing long lists more efficient. - More complicated state management a la React could be done. I'd have a preference for a simpler "this widget tree is the same as the other, don't diff" approach that the user can opt in to.
- Potentially a lot of the diffing code coudld be offloaded to Rust.
- Before doing any of the above, set up benchmarking.
Other
- Sort out distinct naming for custom python commands, TCL commands and subcommands.
Development
uv pip install -e '.[dev]'
mypy .
pytest -vv
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 tkintergalactic-0.0.1.tar.gz.
File metadata
- Download URL: tkintergalactic-0.0.1.tar.gz
- Upload date:
- Size: 13.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
137eaab430a74e62e86c1f3d34251dbae19184bdf6eaf4cf96ed329356286eed
|
|
| MD5 |
136bb5368f2a3cf882b6ad9d154f4b61
|
|
| BLAKE2b-256 |
374b47d913fe1266f8b6ce866f418dfd1ccc62b440689ccba7165fea7668debf
|
File details
Details for the file tkintergalactic-0.0.1-py3-none-any.whl.
File metadata
- Download URL: tkintergalactic-0.0.1-py3-none-any.whl
- Upload date:
- Size: 12.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
393d2bab3b5b31eac56d07838750125162c3a9940c978dd23a7d06e15809cb05
|
|
| MD5 |
60332c410d4c25b73072dd11970bedfd
|
|
| BLAKE2b-256 |
a934bfb2fffa103c88feb082f1ed7db66096e4e5549bc2ec605e606b96a15696
|