nextpytk 0.4.7__tar.gz → 0.4.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nextpytk
3
- Version: 0.4.7
3
+ Version: 0.4.9
4
4
  Summary: Accessible, declarative Tkinter applications from ordinary Python functions.
5
5
  Project-URL: Homepage, https://github.com/nishimotz/nextpytk
6
6
  Project-URL: Repository, https://github.com/nishimotz/nextpytk
@@ -35,7 +35,7 @@ Uses ttk widgets where available.
35
35
 
36
36
  ## Quick Start
37
37
 
38
- Start with an app where a button updates a message.
38
+ Start with an app where a button updates its own label.
39
39
 
40
40
  ```bash
41
41
  pip install nextpytk
@@ -46,59 +46,48 @@ from nextpytk import TkApp
46
46
 
47
47
  app = TkApp(title="Hello")
48
48
 
49
- @app.status("msg")
50
- def msg():
51
- return "Hello, world!"
49
+ @app.button("hello")
50
+ def on_hello():
51
+ return "world"
52
52
 
53
- @app.button("greet", label="Greet")
54
- def on_greet():
55
- return {"msg": "Button clicked!"}
56
-
57
- app.run(layout=["msg", "greet"])
53
+ app.run()
58
54
  ```
59
55
 
56
+ That's it: a window appears with a button labeled `hello`. Press it and the
57
+ label becomes `world`.
58
+
60
59
  ---
61
60
 
62
61
  ## How it works
63
62
 
64
- In nextpytk you register widgets by name and declare layout separately.
65
-
66
- This example registers two widgets: `msg` and `greet`.
67
-
68
- ```python
69
- @app.status("msg")
70
- ```
71
-
72
- `msg` is a status area that shows a message.
63
+ The minimal example packs a lot in. Let's unpack it.
73
64
 
74
65
  ```python
75
- @app.button("greet", label="Greet")
66
+ @app.button("hello")
76
67
  ```
77
68
 
78
- `greet` is a button labeled "Greet".
79
-
80
- Finally, name the display order:
69
+ Registers a button named `hello`. When `label=` is omitted, the widget name is
70
+ used as the button text.
81
71
 
82
72
  ```python
83
- app.run(layout=["msg", "greet"])
73
+ def on_hello():
74
+ return "world"
84
75
  ```
85
76
 
86
- When you press the button, the callback returns this `dict`:
77
+ The callback runs when the button is pressed. Returning a plain string updates
78
+ that button's own label — it's sugar for `{"hello": "world"}`.
87
79
 
88
80
  ```python
89
- {"msg": "Button clicked!"}
81
+ app.run()
90
82
  ```
91
83
 
92
- nextpytk merges that into the app `state`.
93
-
94
- Because `msg` is the name of the registered status area, its text becomes
95
- "Button clicked!".
84
+ With no `layout=`, registered widgets are arranged automatically into a single
85
+ column, so you don't have to declare one for a simple app.
96
86
 
97
- So the basic flow is:
87
+ The basic flow is:
98
88
 
99
89
  * Register widgets by name
100
- * List those names in the layout
101
- * Return a `dict` from a callback
90
+ * Return a `dict` (or a plain string) from a callback
102
91
  * `state` updates and matching widgets refresh
103
92
 
104
93
  ---
@@ -858,6 +847,7 @@ uv run python examples/disk_usage_flat_async.py # ncdu-style viewer (async
858
847
  uv run python examples/paired_demo.py # side-by-side paired layout with y-scroll sync
859
848
  uv run python examples/swap_demo.py # dynamic region switching (Layout.target + @app.swap)
860
849
  uv run python examples/bottom_bar_demo.py # pinned bottom bar (section side="bottom")
850
+ uv run python examples/live_validation.py # live validation via Tcl-var trace ingest (ingest_trace=True)
861
851
  ```
862
852
 
863
853
  ---
@@ -880,6 +870,10 @@ uv run python examples/bottom_bar_demo.py # pinned bottom bar (section sid
880
870
  - **`CustomTkinter`**: Modern look via Canvas rendering. nextpytk takes the opposite approach: use native widgets and embed A11y from the start.
881
871
  - **`TkRouter`** (israel-dryer, author of ttkbootstrap): Declarative view routing with URL-style paths, animated transitions, and history stack. Complements nextpytk's `multiview` — routing vs widget composition.
882
872
 
873
+ ## Changelog
874
+
875
+ See [CHANGES.md](./CHANGES.md) for the full release history.
876
+
883
877
  ## License
884
878
 
885
879
  MIT
@@ -11,7 +11,7 @@ Uses ttk widgets where available.
11
11
 
12
12
  ## Quick Start
13
13
 
14
- Start with an app where a button updates a message.
14
+ Start with an app where a button updates its own label.
15
15
 
16
16
  ```bash
17
17
  pip install nextpytk
@@ -22,59 +22,48 @@ from nextpytk import TkApp
22
22
 
23
23
  app = TkApp(title="Hello")
24
24
 
25
- @app.status("msg")
26
- def msg():
27
- return "Hello, world!"
25
+ @app.button("hello")
26
+ def on_hello():
27
+ return "world"
28
28
 
29
- @app.button("greet", label="Greet")
30
- def on_greet():
31
- return {"msg": "Button clicked!"}
32
-
33
- app.run(layout=["msg", "greet"])
29
+ app.run()
34
30
  ```
35
31
 
32
+ That's it: a window appears with a button labeled `hello`. Press it and the
33
+ label becomes `world`.
34
+
36
35
  ---
37
36
 
38
37
  ## How it works
39
38
 
40
- In nextpytk you register widgets by name and declare layout separately.
41
-
42
- This example registers two widgets: `msg` and `greet`.
43
-
44
- ```python
45
- @app.status("msg")
46
- ```
47
-
48
- `msg` is a status area that shows a message.
39
+ The minimal example packs a lot in. Let's unpack it.
49
40
 
50
41
  ```python
51
- @app.button("greet", label="Greet")
42
+ @app.button("hello")
52
43
  ```
53
44
 
54
- `greet` is a button labeled "Greet".
55
-
56
- Finally, name the display order:
45
+ Registers a button named `hello`. When `label=` is omitted, the widget name is
46
+ used as the button text.
57
47
 
58
48
  ```python
59
- app.run(layout=["msg", "greet"])
49
+ def on_hello():
50
+ return "world"
60
51
  ```
61
52
 
62
- When you press the button, the callback returns this `dict`:
53
+ The callback runs when the button is pressed. Returning a plain string updates
54
+ that button's own label — it's sugar for `{"hello": "world"}`.
63
55
 
64
56
  ```python
65
- {"msg": "Button clicked!"}
57
+ app.run()
66
58
  ```
67
59
 
68
- nextpytk merges that into the app `state`.
69
-
70
- Because `msg` is the name of the registered status area, its text becomes
71
- "Button clicked!".
60
+ With no `layout=`, registered widgets are arranged automatically into a single
61
+ column, so you don't have to declare one for a simple app.
72
62
 
73
- So the basic flow is:
63
+ The basic flow is:
74
64
 
75
65
  * Register widgets by name
76
- * List those names in the layout
77
- * Return a `dict` from a callback
66
+ * Return a `dict` (or a plain string) from a callback
78
67
  * `state` updates and matching widgets refresh
79
68
 
80
69
  ---
@@ -834,6 +823,7 @@ uv run python examples/disk_usage_flat_async.py # ncdu-style viewer (async
834
823
  uv run python examples/paired_demo.py # side-by-side paired layout with y-scroll sync
835
824
  uv run python examples/swap_demo.py # dynamic region switching (Layout.target + @app.swap)
836
825
  uv run python examples/bottom_bar_demo.py # pinned bottom bar (section side="bottom")
826
+ uv run python examples/live_validation.py # live validation via Tcl-var trace ingest (ingest_trace=True)
837
827
  ```
838
828
 
839
829
  ---
@@ -856,6 +846,10 @@ uv run python examples/bottom_bar_demo.py # pinned bottom bar (section sid
856
846
  - **`CustomTkinter`**: Modern look via Canvas rendering. nextpytk takes the opposite approach: use native widgets and embed A11y from the start.
857
847
  - **`TkRouter`** (israel-dryer, author of ttkbootstrap): Declarative view routing with URL-style paths, animated transitions, and history stack. Complements nextpytk's `multiview` — routing vs widget composition.
858
848
 
849
+ ## Changelog
850
+
851
+ See [CHANGES.md](./CHANGES.md) for the full release history.
852
+
859
853
  ## License
860
854
 
861
855
  MIT
@@ -0,0 +1,61 @@
1
+ # ROADMAP — nextpytk
2
+
3
+ > **Note:** Past release history lives in [CHANGES.md](./CHANGES.md).
4
+ > This file is the forward-looking plan (near-term, then v0.5.0, then longer term).
5
+
6
+ ## Near term (post-0.4.8)
7
+
8
+ ### A11y
9
+
10
+ - [ ] `@app.status` live-region behavior (ARIA `aria-live` equivalent / WCAG 4.1.3)
11
+ - [ ] Tk 9.1 `tk accessible set_acc_*` real-device verification (9.1b0 + NVDA)
12
+ - [ ] Role vocabulary mapping to Tk side
13
+ - [ ] Automatic `emit_selection_change` (leverage `apply_state` knowing which widgets changed)
14
+
15
+ ### Type hints
16
+
17
+ - [ ] Further TypedDict / Protocol coverage for decorator arguments
18
+ - [ ] Fluent API equivalent to `_GridBuilder.columnconfigure`
19
+
20
+ ### Widget expansion
21
+
22
+ - [ ] Per-widget `bind` for other widgets (`text`, `combobox`, `treeview`, `button`, etc.)
23
+ - [ ] `@app.filepicker` — `filedialog` wrapper (schema/tool naming still open)
24
+
25
+ ### Layout DSL
26
+
27
+ - [ ] CSS-grid-inspired layout API for 0.5.0: explicit `grid-template-columns` / `grid-template-rows` strings (e.g. `"1fr 2fr"`, `"auto 1fr"`), area-based placement, and gap tokens. Reduce misuse by making rows/columns and widget placement visually aligned in one declaration.
28
+ - [ ] Wire visual Tab order for `side="bottom"` sections via `_wire_tab_order` (see v0.4.6 note in CHANGES.md).
29
+
30
+ ### Agent / LLM integration
31
+
32
+ - [ ] Expose `schema()` as Function Calling definition (bind `sequence`, treeview column defs, etc.)
33
+ - [ ] `@agent_tool` integration (GUI operations as agent vocabulary)
34
+ - [ ] Surface `@app.filepicker` in `schema()` / tool vocabulary
35
+
36
+ ---
37
+
38
+ ## v0.5.0 — themes / chrome decoupling
39
+
40
+ - Remove deprecated `theme=True/False` support; `theme` becomes `str` only.
41
+ - Remove deprecated `EventSeq.DOUBLE_CLICK`; use `EventSeq.PRIMARY_DOUBLE_CLICK` or `DOUBLE_BUTTON_1`.
42
+ - Remove deprecated index-order plural methods `col_weights`/`row_weights`/`col_minsizes`/`row_minsizes` and `Layout.cluster()` alias.
43
+ - Decouple `Layout().header()` / `.status()` chrome from Kizashi-specific tokens so they render safely with any ttk theme (`"none"`, `"clam"`, etc.).
44
+ - Extract Kizashi as a standalone ttk theme package so it can be proposed upstream or reused independently of nextpytk.
45
+
46
+ ---
47
+
48
+ ## Longer term
49
+
50
+ ### ttk Style layer
51
+
52
+ - [ ] `Layout.style("my_button", background=..., font=...)` style definitions
53
+
54
+ ### Declarative components
55
+
56
+ - [ ] `@app.component` decorator (React-like reuse, replacing `Layout`)
57
+ - [ ] State type definitions and validation (no Pydantic)
58
+
59
+ ### Testing
60
+
61
+ - [ ] WidgetSpec unit tests
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "nextpytk"
7
- version = "0.4.7"
7
+ version = "0.4.9"
8
8
  description = "Accessible, declarative Tkinter applications from ordinary Python functions."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"