CTkKanBan 1.0.0__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.
- ctkkanban-1.0.0/.gitattributes +18 -0
- ctkkanban-1.0.0/CHANGELOG.md +37 -0
- ctkkanban-1.0.0/CODE_OF_CONDUCT.md +14 -0
- ctkkanban-1.0.0/CONTRIBUTING.md +13 -0
- ctkkanban-1.0.0/CTkKanBan/__init__.py +10 -0
- ctkkanban-1.0.0/CTkKanBan.egg-info/PKG-INFO +193 -0
- ctkkanban-1.0.0/CTkKanBan.egg-info/SOURCES.txt +74 -0
- ctkkanban-1.0.0/CTkKanBan.egg-info/dependency_links.txt +1 -0
- ctkkanban-1.0.0/CTkKanBan.egg-info/requires.txt +38 -0
- ctkkanban-1.0.0/CTkKanBan.egg-info/top_level.txt +2 -0
- ctkkanban-1.0.0/LICENSE +21 -0
- ctkkanban-1.0.0/MANIFEST.in +14 -0
- ctkkanban-1.0.0/PKG-INFO +193 -0
- ctkkanban-1.0.0/README.md +128 -0
- ctkkanban-1.0.0/SECURITY.md +16 -0
- ctkkanban-1.0.0/ctk_kanban/__init__.py +86 -0
- ctkkanban-1.0.0/ctk_kanban/board.py +3554 -0
- ctkkanban-1.0.0/ctk_kanban/card.py +1072 -0
- ctkkanban-1.0.0/ctk_kanban/column.py +488 -0
- ctkkanban-1.0.0/ctk_kanban/contracts.py +181 -0
- ctkkanban-1.0.0/ctk_kanban/crud.py +638 -0
- ctkkanban-1.0.0/ctk_kanban/datasource.py +564 -0
- ctkkanban-1.0.0/ctk_kanban/dialogs.py +974 -0
- ctkkanban-1.0.0/ctk_kanban/drag.py +430 -0
- ctkkanban-1.0.0/ctk_kanban/events.py +31 -0
- ctkkanban-1.0.0/ctk_kanban/exceptions.py +29 -0
- ctkkanban-1.0.0/ctk_kanban/models.py +162 -0
- ctkkanban-1.0.0/ctk_kanban/py.typed +1 -0
- ctkkanban-1.0.0/ctk_kanban/query.py +132 -0
- ctkkanban-1.0.0/ctk_kanban/rendering.py +622 -0
- ctkkanban-1.0.0/ctk_kanban/sqlite.py +854 -0
- ctkkanban-1.0.0/ctk_kanban/themes.py +216 -0
- ctkkanban-1.0.0/ctk_kanban/toolbar.py +447 -0
- ctkkanban-1.0.0/ctk_kanban/utils.py +170 -0
- ctkkanban-1.0.0/ctk_kanban/validators.py +322 -0
- ctkkanban-1.0.0/ctk_kanban/version.py +3 -0
- ctkkanban-1.0.0/ctk_kanban/widgets.py +453 -0
- ctkkanban-1.0.0/docs/assests/favicon/about.txt +6 -0
- ctkkanban-1.0.0/docs/assests/favicon/android-chrome-192x192.png +0 -0
- ctkkanban-1.0.0/docs/assests/favicon/android-chrome-512x512.png +0 -0
- ctkkanban-1.0.0/docs/assests/favicon/apple-touch-icon.png +0 -0
- ctkkanban-1.0.0/docs/assests/favicon/favicon-16x16.png +0 -0
- ctkkanban-1.0.0/docs/assests/favicon/favicon-32x32.png +0 -0
- ctkkanban-1.0.0/docs/assests/favicon/favicon.ico +0 -0
- ctkkanban-1.0.0/docs/assests/favicon/site.webmanifest +1 -0
- ctkkanban-1.0.0/docs/database.md +213 -0
- ctkkanban-1.0.0/docs/index.html +3510 -0
- ctkkanban-1.0.0/docs/publishing.md +74 -0
- ctkkanban-1.0.0/docs/script.js +266 -0
- ctkkanban-1.0.0/docs/styles.css +901 -0
- ctkkanban-1.0.0/example_all_features.py +270 -0
- ctkkanban-1.0.0/example_sqlite.py +53 -0
- ctkkanban-1.0.0/pyproject.toml +154 -0
- ctkkanban-1.0.0/scripts/check_docs.py +232 -0
- ctkkanban-1.0.0/scripts/prepare_release.py +63 -0
- ctkkanban-1.0.0/scripts/run_actionlint.py +85 -0
- ctkkanban-1.0.0/scripts/smoke_install.py +80 -0
- ctkkanban-1.0.0/scripts/validate_dist.py +38 -0
- ctkkanban-1.0.0/scripts/verify_release.py +155 -0
- ctkkanban-1.0.0/setup.cfg +4 -0
- ctkkanban-1.0.0/tests/gui_test_app.py +6 -0
- ctkkanban-1.0.0/tests/test_board_integrity_regressions.py +212 -0
- ctkkanban-1.0.0/tests/test_card_creation_optimizations.py +129 -0
- ctkkanban-1.0.0/tests/test_card_form_modes.py +114 -0
- ctkkanban-1.0.0/tests/test_crud_datasource.py +369 -0
- ctkkanban-1.0.0/tests/test_database_persistence_api.py +98 -0
- ctkkanban-1.0.0/tests/test_drag_optimizations.py +121 -0
- ctkkanban-1.0.0/tests/test_full_efficiency_audit.py +229 -0
- ctkkanban-1.0.0/tests/test_inline_card_editing.py +931 -0
- ctkkanban-1.0.0/tests/test_new_usability_features.py +209 -0
- ctkkanban-1.0.0/tests/test_performance_regressions.py +43 -0
- ctkkanban-1.0.0/tests/test_persistence_correctness.py +688 -0
- ctkkanban-1.0.0/tests/test_release_validation.py +48 -0
- ctkkanban-1.0.0/tests/test_sqlite_datasource.py +191 -0
- ctkkanban-1.0.0/tests/test_style_customization.py +201 -0
- ctkkanban-1.0.0/tox.ini +49 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
* text=auto
|
|
2
|
+
|
|
3
|
+
.gitattributes text eol=lf
|
|
4
|
+
.gitignore text eol=lf
|
|
5
|
+
MANIFEST.in text eol=lf
|
|
6
|
+
*.css text eol=lf
|
|
7
|
+
*.html text eol=lf
|
|
8
|
+
*.ini text eol=lf
|
|
9
|
+
*.js text eol=lf
|
|
10
|
+
*.json text eol=lf
|
|
11
|
+
*.md text eol=lf
|
|
12
|
+
*.py text eol=lf
|
|
13
|
+
*.toml text eol=lf
|
|
14
|
+
*.yaml text eol=lf
|
|
15
|
+
*.yml text eol=lf
|
|
16
|
+
|
|
17
|
+
*.ico binary
|
|
18
|
+
*.png binary
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 1.0.0 - 2026-07-24
|
|
6
|
+
|
|
7
|
+
- Added live, field-aware editing inside default cards, including empty-field placeholders, typed controls, keyboard save/cancel behavior, validation feedback, and persistence through the normal card update pipeline.
|
|
8
|
+
- Added `enable_inline_card_editing` and `start_inline_card_edit()` while retaining the explicit popup and side-panel form APIs for compatibility.
|
|
9
|
+
- Kept invalid inline edits from triggering release-driven host controls under CustomTkinter 6 while preserving CustomTkinter 5 behavior.
|
|
10
|
+
|
|
11
|
+
## 0.3.0 - 2026-07-24
|
|
12
|
+
|
|
13
|
+
- Added `CRUDKanbanDataSource`, a four-callback bridge for connecting existing SQL, NoSQL, ORM, and API repositories without implementing the full persistence protocol.
|
|
14
|
+
- Hardened SQLite mutation replay, schema migration, conflict snapshots, batch rollback, identifier validation, and offline queue ordering.
|
|
15
|
+
- Fixed paged-board totals, offsets, undo/redo persistence, column rename handling, timestamp sorting, dirty-form replacement, and style snapshots.
|
|
16
|
+
- Expanded supported CustomTkinter releases through 6.x and strengthened source/wheel validation, compatibility testing, documentation checks, and release smoke tests.
|
|
17
|
+
- Added cross-platform CI for Python 3.10 through 3.14, branch coverage, dependency auditing, installed-wheel smoke tests, and package validation.
|
|
18
|
+
- Added CodeQL scanning, Dependabot, workflow security linting, GitHub Pages deployment, and repository contribution templates.
|
|
19
|
+
- Added trusted TestPyPI and PyPI publishing with protected environments, artifact attestations, checksums, and automated GitHub releases.
|
|
20
|
+
- Added local tox environments and release preparation, validation, and installed-package smoke-test scripts.
|
|
21
|
+
|
|
22
|
+
## 0.2.0 - 2026-06-14
|
|
23
|
+
|
|
24
|
+
- Added typed mutation, result, conflict, query, paging, and load contracts.
|
|
25
|
+
- Added threaded data-source coordination, retries, offline queueing, polling, canonical IDs, and optimistic concurrency.
|
|
26
|
+
- Added a transactional SQLite adapter and runnable database example.
|
|
27
|
+
- Added sparse card ranking, atomic batches, undo/redo, immutable IDs, timestamps, and revisions.
|
|
28
|
+
- Added persistence status, filter chips, active sort and result summaries, search clearing and highlighting.
|
|
29
|
+
- Added responsive and adjustable columns, drag handles, WIP/lock indicators, and invalid-drop feedback.
|
|
30
|
+
- Added date picking, field-level validation, dirty-form protection, and normalized optional values.
|
|
31
|
+
- Redesigned the default light and dark appearance with layered surfaces, priority rails, metadata tiles, compact toolbar states, polished columns, and cohesive forms.
|
|
32
|
+
- Added visual-state regression coverage and light/dark/form showcase modes.
|
|
33
|
+
- Added integration, performance, reliability, and usability tests.
|
|
34
|
+
|
|
35
|
+
## 0.1.0
|
|
36
|
+
|
|
37
|
+
- Initial configurable CustomTkinter Kanban board.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our standard
|
|
4
|
+
|
|
5
|
+
We want participation in CTkKanban to be welcoming, constructive, and safe. Be respectful, assume good intent while still discussing technical disagreements directly, and focus criticism on behavior and code rather than people.
|
|
6
|
+
|
|
7
|
+
Harassment, discrimination, threats, sexualized attention, deliberate intimidation, and publication of private information are not acceptable.
|
|
8
|
+
|
|
9
|
+
## Enforcement
|
|
10
|
+
|
|
11
|
+
Report conduct concerns privately to the project maintainer through GitHub. The maintainer may edit or remove contributions, limit participation, or ban contributors when needed to protect the community. Reports will be handled as confidentially as practical.
|
|
12
|
+
|
|
13
|
+
This policy applies in project spaces and when someone is publicly representing the project.
|
|
14
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
1. Create a virtual environment with Python 3.10 or newer.
|
|
4
|
+
2. Install the project in editable mode: `python -m pip install -e ".[dev]"`.
|
|
5
|
+
3. Keep public mutations database-neutral and operation-first.
|
|
6
|
+
4. Add focused tests for behavior, rollback, thread boundaries, and widget identity.
|
|
7
|
+
5. Run `tox -e lint,type,py314,package` before opening a change.
|
|
8
|
+
|
|
9
|
+
Tk widgets must only be touched by Tk's owning thread. Persistence adapters may block because the coordinator runs them on a dedicated worker.
|
|
10
|
+
|
|
11
|
+
Do not introduce a second persistence writer into a board. Use a `KanbanDataSource` or the legacy `on_data_changed` callback.
|
|
12
|
+
|
|
13
|
+
User-visible changes belong under `## Unreleased` in `CHANGELOG.md`. See [docs/publishing.md](docs/publishing.md) for TestPyPI and production release steps.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""Public compatibility import for the CTkKanBan distribution.
|
|
2
|
+
|
|
3
|
+
The implementation lives in :mod:`ctk_kanban`; this package preserves the
|
|
4
|
+
project's branded import spelling for applications that prefer ``import
|
|
5
|
+
CTkKanBan``.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from ctk_kanban import * # noqa: F401,F403
|
|
9
|
+
from ctk_kanban import __all__, __version__
|
|
10
|
+
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: CTkKanBan
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A configurable, database-ready Kanban board for CustomTkinter
|
|
5
|
+
Author-email: Harry Gomm <Harry-g25@users.noreply.github.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Harry-g25/CTkKanBan
|
|
8
|
+
Project-URL: Documentation, https://harry-g25.github.io/CTkKanBan/
|
|
9
|
+
Project-URL: Changelog, https://github.com/Harry-g25/CTkKanBan/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Issues, https://github.com/Harry-g25/CTkKanBan/issues
|
|
11
|
+
Project-URL: Source, https://github.com/Harry-g25/CTkKanBan
|
|
12
|
+
Keywords: customtkinter,kanban,desktop,sqlite,database,gui
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Win32 (MS Windows)
|
|
15
|
+
Classifier: Environment :: X11 Applications
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: Operating System :: MacOS
|
|
18
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
19
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
27
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
28
|
+
Classifier: Typing :: Typed
|
|
29
|
+
Requires-Python: >=3.10
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
License-File: LICENSE
|
|
32
|
+
Requires-Dist: customtkinter<7,>=5.2.2
|
|
33
|
+
Requires-Dist: tzdata>=2025.2; platform_system == "Windows"
|
|
34
|
+
Provides-Extra: test
|
|
35
|
+
Requires-Dist: coverage[toml]>=7.6; extra == "test"
|
|
36
|
+
Requires-Dist: pytest>=8.3; extra == "test"
|
|
37
|
+
Requires-Dist: pytest-cov>=6; extra == "test"
|
|
38
|
+
Provides-Extra: quality
|
|
39
|
+
Requires-Dist: mypy>=1.14; extra == "quality"
|
|
40
|
+
Requires-Dist: ruff>=0.9; extra == "quality"
|
|
41
|
+
Requires-Dist: yamllint>=1.35; extra == "quality"
|
|
42
|
+
Requires-Dist: zizmor>=1.7; extra == "quality"
|
|
43
|
+
Provides-Extra: release
|
|
44
|
+
Requires-Dist: build>=1.2; extra == "release"
|
|
45
|
+
Requires-Dist: check-wheel-contents>=0.6; extra == "release"
|
|
46
|
+
Requires-Dist: packaging>=24; extra == "release"
|
|
47
|
+
Requires-Dist: pyroma>=4.2; extra == "release"
|
|
48
|
+
Requires-Dist: twine>=6; extra == "release"
|
|
49
|
+
Provides-Extra: dev
|
|
50
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
51
|
+
Requires-Dist: check-wheel-contents>=0.6; extra == "dev"
|
|
52
|
+
Requires-Dist: coverage[toml]>=7.6; extra == "dev"
|
|
53
|
+
Requires-Dist: mypy>=1.14; extra == "dev"
|
|
54
|
+
Requires-Dist: packaging>=24; extra == "dev"
|
|
55
|
+
Requires-Dist: pip-audit>=2.7; extra == "dev"
|
|
56
|
+
Requires-Dist: pyroma>=4.2; extra == "dev"
|
|
57
|
+
Requires-Dist: pytest>=8.3; extra == "dev"
|
|
58
|
+
Requires-Dist: pytest-cov>=6; extra == "dev"
|
|
59
|
+
Requires-Dist: ruff>=0.9; extra == "dev"
|
|
60
|
+
Requires-Dist: tox>=4.23; extra == "dev"
|
|
61
|
+
Requires-Dist: twine>=6; extra == "dev"
|
|
62
|
+
Requires-Dist: yamllint>=1.35; extra == "dev"
|
|
63
|
+
Requires-Dist: zizmor>=1.7; extra == "dev"
|
|
64
|
+
Dynamic: license-file
|
|
65
|
+
|
|
66
|
+
# CTkKanban
|
|
67
|
+
|
|
68
|
+
[](https://github.com/Harry-g25/CTkKanBan/actions/workflows/ci.yml)
|
|
69
|
+
[](https://github.com/Harry-g25/CTkKanBan/actions/workflows/codeql.yml)
|
|
70
|
+
[](https://pypi.org/project/CTkKanBan/)
|
|
71
|
+
[](https://pypi.org/project/CTkKanBan/)
|
|
72
|
+
[](https://github.com/Harry-g25/CTkKanBan/blob/main/LICENSE)
|
|
73
|
+
|
|
74
|
+
CTkKanban is a configurable Kanban widget for CustomTkinter desktop applications. It ships with a polished adaptive light/dark design, live inline card editing, generated forms, drag and drop, search, advanced filters, sorting, undo/redo, responsive columns, and database-backed operation.
|
|
75
|
+
|
|
76
|
+
The built-in design uses layered surfaces, priority-accented cards, responsive metadata tiles, column color rails, active filter treatments, and database status pills. Every visual token remains overridable through `style` or `theme`.
|
|
77
|
+
|
|
78
|
+
## Install
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
python -m pip install CTkKanBan
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## In-memory board
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
import customtkinter as ctk
|
|
88
|
+
import CTkKanBan
|
|
89
|
+
|
|
90
|
+
board_class = CTkKanBan.CTkKanbanBoard
|
|
91
|
+
|
|
92
|
+
app = ctk.CTk()
|
|
93
|
+
board = board_class(
|
|
94
|
+
app,
|
|
95
|
+
columns=[{"id": "todo", "title": "To Do"}, {"id": "done", "title": "Done"}],
|
|
96
|
+
cards=[{"id": 1, "column": "todo", "title": "Try CTkKanban"}],
|
|
97
|
+
completed_columns=["done"],
|
|
98
|
+
)
|
|
99
|
+
board.pack(fill="both", expand=True)
|
|
100
|
+
app.mainloop()
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Inline card editing
|
|
104
|
+
|
|
105
|
+
Inline editing is enabled by default. Click any value rendered on a card—including an empty
|
|
106
|
+
`show_on_card` field—to edit it without opening a dialog. Press Enter or click the check button to
|
|
107
|
+
save, click away to autosave, or press Escape to cancel. Text areas use Ctrl+Enter to save so Enter
|
|
108
|
+
can still insert a new line.
|
|
109
|
+
|
|
110
|
+
Edits use the same validation, callbacks, undo history, filtering, sorting, and persistence path as
|
|
111
|
+
`update_card()`. Read-only and hidden fields are never editable. To keep the earlier popup/side-panel
|
|
112
|
+
interaction, configure `enable_inline_card_editing=False`; `open_edit_card_form(card_id)` also remains
|
|
113
|
+
available for an explicit full-card form.
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
board = CTkKanbanBoard(
|
|
117
|
+
app,
|
|
118
|
+
columns=columns,
|
|
119
|
+
cards=cards,
|
|
120
|
+
fields=fields,
|
|
121
|
+
enable_inline_card_editing=True,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
# Keyboard-free or application-driven activation is also available.
|
|
125
|
+
board.start_inline_card_edit(card_id=1, field_key="priority")
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Automatic field hit targets are available with the default card renderer. Applications using a
|
|
129
|
+
custom `card_renderer` retain the full-card edit flow and can build their own editing controls.
|
|
130
|
+
|
|
131
|
+
## SQLite board
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
import customtkinter as ctk
|
|
135
|
+
from ctk_kanban import CTkKanbanBoard, SQLiteKanbanDataSource
|
|
136
|
+
|
|
137
|
+
app = ctk.CTk()
|
|
138
|
+
source = SQLiteKanbanDataSource("kanban.db")
|
|
139
|
+
source.seed_board("work", [{"id": "todo", "title": "To Do"}], [])
|
|
140
|
+
|
|
141
|
+
board = CTkKanbanBoard(
|
|
142
|
+
app,
|
|
143
|
+
data_source=source,
|
|
144
|
+
board_id="work",
|
|
145
|
+
auto_load=True,
|
|
146
|
+
server_side_query=True,
|
|
147
|
+
poll_interval_ms=2000,
|
|
148
|
+
)
|
|
149
|
+
board.pack(fill="both", expand=True)
|
|
150
|
+
app.mainloop()
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Database work runs outside Tk's UI thread. Mutations carry event, transaction, actor, board, and expected-revision metadata. Adapters may return canonical records with generated IDs, timestamps, versions, and defaults. Failed network writes can be retried or held in the process-local offline queue until connectivity returns.
|
|
154
|
+
|
|
155
|
+
The built-in SQLite adapter provides transactional writes, optimistic revisions, atomic batches, server-side search/filter/sort, paging, change polling, generated IDs, and automatic timestamps. The board shows saving, saved, offline, conflict, and error states; duplicate submissions are blocked while a mutation is pending.
|
|
156
|
+
|
|
157
|
+
For an existing SQL, document, key-value, ORM, or API-backed repository, use
|
|
158
|
+
`CRUDKanbanDataSource` instead of implementing the full adapter contract:
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
from ctk_kanban import CRUDKanbanDataSource
|
|
162
|
+
|
|
163
|
+
source = CRUDKanbanDataSource(
|
|
164
|
+
read=repository.read_board,
|
|
165
|
+
create=repository.create,
|
|
166
|
+
update=repository.update,
|
|
167
|
+
delete=repository.delete,
|
|
168
|
+
transaction=repository.transaction, # Optional
|
|
169
|
+
)
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
The four callbacks receive either `"card"` or `"column"`, the board ID, the record or ID, and a
|
|
173
|
+
`CRUDContext`. The bridge translates moves, reorders, renames, batching, paging, search, filters, and
|
|
174
|
+
canonical generated IDs. This keeps database-specific connection and query code in your application.
|
|
175
|
+
|
|
176
|
+
Use only one durable writer: configure either `data_source` or the legacy `on_data_changed` callback, never both.
|
|
177
|
+
|
|
178
|
+
See the [database integration guide](https://github.com/Harry-g25/CTkKanBan/blob/main/docs/database.md) for the adapter contract, event shape, conflict policies, paging, polling, and a production integration checklist.
|
|
179
|
+
|
|
180
|
+
The example programs are included in the source repository and source distribution, not the installed wheel. From a [source checkout](https://github.com/Harry-g25/CTkKanBan), run `python example_all_features.py` for the UI showcase or `python example_sqlite.py` for the transactional database example.
|
|
181
|
+
|
|
182
|
+
Use `python example_all_features.py --light`, `--dark`, or `--form` to inspect specific appearance and form states. Add `--diagnose` to print the exact package path and version being rendered.
|
|
183
|
+
|
|
184
|
+
## Development
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
python -m pip install -e ".[dev]"
|
|
188
|
+
tox -e lint,type,py314,ctk-min,ctk-current,package
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
CI tests Python 3.10 through 3.14 on Linux and the oldest/latest supported versions on Windows and macOS. It also checks branch coverage, installed-wheel behavior, SQLite persistence, dependency vulnerabilities, package metadata, and workflow security.
|
|
192
|
+
|
|
193
|
+
See the [changelog](https://github.com/Harry-g25/CTkKanBan/blob/main/CHANGELOG.md), [contribution guide](https://github.com/Harry-g25/CTkKanBan/blob/main/CONTRIBUTING.md), [publishing runbook](https://github.com/Harry-g25/CTkKanBan/blob/main/docs/publishing.md), and [project documentation](https://harry-g25.github.io/CTkKanBan/).
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
.gitattributes
|
|
2
|
+
CHANGELOG.md
|
|
3
|
+
CODE_OF_CONDUCT.md
|
|
4
|
+
CONTRIBUTING.md
|
|
5
|
+
LICENSE
|
|
6
|
+
MANIFEST.in
|
|
7
|
+
README.md
|
|
8
|
+
SECURITY.md
|
|
9
|
+
example_all_features.py
|
|
10
|
+
example_sqlite.py
|
|
11
|
+
pyproject.toml
|
|
12
|
+
tox.ini
|
|
13
|
+
CTkKanBan/__init__.py
|
|
14
|
+
CTkKanBan.egg-info/PKG-INFO
|
|
15
|
+
CTkKanBan.egg-info/SOURCES.txt
|
|
16
|
+
CTkKanBan.egg-info/dependency_links.txt
|
|
17
|
+
CTkKanBan.egg-info/requires.txt
|
|
18
|
+
CTkKanBan.egg-info/top_level.txt
|
|
19
|
+
ctk_kanban/__init__.py
|
|
20
|
+
ctk_kanban/board.py
|
|
21
|
+
ctk_kanban/card.py
|
|
22
|
+
ctk_kanban/column.py
|
|
23
|
+
ctk_kanban/contracts.py
|
|
24
|
+
ctk_kanban/crud.py
|
|
25
|
+
ctk_kanban/datasource.py
|
|
26
|
+
ctk_kanban/dialogs.py
|
|
27
|
+
ctk_kanban/drag.py
|
|
28
|
+
ctk_kanban/events.py
|
|
29
|
+
ctk_kanban/exceptions.py
|
|
30
|
+
ctk_kanban/models.py
|
|
31
|
+
ctk_kanban/py.typed
|
|
32
|
+
ctk_kanban/query.py
|
|
33
|
+
ctk_kanban/rendering.py
|
|
34
|
+
ctk_kanban/sqlite.py
|
|
35
|
+
ctk_kanban/themes.py
|
|
36
|
+
ctk_kanban/toolbar.py
|
|
37
|
+
ctk_kanban/utils.py
|
|
38
|
+
ctk_kanban/validators.py
|
|
39
|
+
ctk_kanban/version.py
|
|
40
|
+
ctk_kanban/widgets.py
|
|
41
|
+
docs/database.md
|
|
42
|
+
docs/index.html
|
|
43
|
+
docs/publishing.md
|
|
44
|
+
docs/script.js
|
|
45
|
+
docs/styles.css
|
|
46
|
+
docs/assests/favicon/about.txt
|
|
47
|
+
docs/assests/favicon/android-chrome-192x192.png
|
|
48
|
+
docs/assests/favicon/android-chrome-512x512.png
|
|
49
|
+
docs/assests/favicon/apple-touch-icon.png
|
|
50
|
+
docs/assests/favicon/favicon-16x16.png
|
|
51
|
+
docs/assests/favicon/favicon-32x32.png
|
|
52
|
+
docs/assests/favicon/favicon.ico
|
|
53
|
+
docs/assests/favicon/site.webmanifest
|
|
54
|
+
scripts/check_docs.py
|
|
55
|
+
scripts/prepare_release.py
|
|
56
|
+
scripts/run_actionlint.py
|
|
57
|
+
scripts/smoke_install.py
|
|
58
|
+
scripts/validate_dist.py
|
|
59
|
+
scripts/verify_release.py
|
|
60
|
+
tests/gui_test_app.py
|
|
61
|
+
tests/test_board_integrity_regressions.py
|
|
62
|
+
tests/test_card_creation_optimizations.py
|
|
63
|
+
tests/test_card_form_modes.py
|
|
64
|
+
tests/test_crud_datasource.py
|
|
65
|
+
tests/test_database_persistence_api.py
|
|
66
|
+
tests/test_drag_optimizations.py
|
|
67
|
+
tests/test_full_efficiency_audit.py
|
|
68
|
+
tests/test_inline_card_editing.py
|
|
69
|
+
tests/test_new_usability_features.py
|
|
70
|
+
tests/test_performance_regressions.py
|
|
71
|
+
tests/test_persistence_correctness.py
|
|
72
|
+
tests/test_release_validation.py
|
|
73
|
+
tests/test_sqlite_datasource.py
|
|
74
|
+
tests/test_style_customization.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
customtkinter<7,>=5.2.2
|
|
2
|
+
|
|
3
|
+
[:platform_system == "Windows"]
|
|
4
|
+
tzdata>=2025.2
|
|
5
|
+
|
|
6
|
+
[dev]
|
|
7
|
+
build>=1.2
|
|
8
|
+
check-wheel-contents>=0.6
|
|
9
|
+
coverage[toml]>=7.6
|
|
10
|
+
mypy>=1.14
|
|
11
|
+
packaging>=24
|
|
12
|
+
pip-audit>=2.7
|
|
13
|
+
pyroma>=4.2
|
|
14
|
+
pytest>=8.3
|
|
15
|
+
pytest-cov>=6
|
|
16
|
+
ruff>=0.9
|
|
17
|
+
tox>=4.23
|
|
18
|
+
twine>=6
|
|
19
|
+
yamllint>=1.35
|
|
20
|
+
zizmor>=1.7
|
|
21
|
+
|
|
22
|
+
[quality]
|
|
23
|
+
mypy>=1.14
|
|
24
|
+
ruff>=0.9
|
|
25
|
+
yamllint>=1.35
|
|
26
|
+
zizmor>=1.7
|
|
27
|
+
|
|
28
|
+
[release]
|
|
29
|
+
build>=1.2
|
|
30
|
+
check-wheel-contents>=0.6
|
|
31
|
+
packaging>=24
|
|
32
|
+
pyroma>=4.2
|
|
33
|
+
twine>=6
|
|
34
|
+
|
|
35
|
+
[test]
|
|
36
|
+
coverage[toml]>=7.6
|
|
37
|
+
pytest>=8.3
|
|
38
|
+
pytest-cov>=6
|
ctkkanban-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Harry Gomm
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
include .gitattributes
|
|
2
|
+
include CHANGELOG.md
|
|
3
|
+
include CODE_OF_CONDUCT.md
|
|
4
|
+
include CONTRIBUTING.md
|
|
5
|
+
include LICENSE
|
|
6
|
+
include README.md
|
|
7
|
+
include SECURITY.md
|
|
8
|
+
include example_all_features.py
|
|
9
|
+
include example_sqlite.py
|
|
10
|
+
include tests/gui_test_app.py
|
|
11
|
+
include tox.ini
|
|
12
|
+
recursive-include docs *
|
|
13
|
+
recursive-include scripts *.py
|
|
14
|
+
include ctk_kanban/py.typed
|
ctkkanban-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: CTkKanBan
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A configurable, database-ready Kanban board for CustomTkinter
|
|
5
|
+
Author-email: Harry Gomm <Harry-g25@users.noreply.github.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Harry-g25/CTkKanBan
|
|
8
|
+
Project-URL: Documentation, https://harry-g25.github.io/CTkKanBan/
|
|
9
|
+
Project-URL: Changelog, https://github.com/Harry-g25/CTkKanBan/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Issues, https://github.com/Harry-g25/CTkKanBan/issues
|
|
11
|
+
Project-URL: Source, https://github.com/Harry-g25/CTkKanBan
|
|
12
|
+
Keywords: customtkinter,kanban,desktop,sqlite,database,gui
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Win32 (MS Windows)
|
|
15
|
+
Classifier: Environment :: X11 Applications
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: Operating System :: MacOS
|
|
18
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
19
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
27
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
28
|
+
Classifier: Typing :: Typed
|
|
29
|
+
Requires-Python: >=3.10
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
License-File: LICENSE
|
|
32
|
+
Requires-Dist: customtkinter<7,>=5.2.2
|
|
33
|
+
Requires-Dist: tzdata>=2025.2; platform_system == "Windows"
|
|
34
|
+
Provides-Extra: test
|
|
35
|
+
Requires-Dist: coverage[toml]>=7.6; extra == "test"
|
|
36
|
+
Requires-Dist: pytest>=8.3; extra == "test"
|
|
37
|
+
Requires-Dist: pytest-cov>=6; extra == "test"
|
|
38
|
+
Provides-Extra: quality
|
|
39
|
+
Requires-Dist: mypy>=1.14; extra == "quality"
|
|
40
|
+
Requires-Dist: ruff>=0.9; extra == "quality"
|
|
41
|
+
Requires-Dist: yamllint>=1.35; extra == "quality"
|
|
42
|
+
Requires-Dist: zizmor>=1.7; extra == "quality"
|
|
43
|
+
Provides-Extra: release
|
|
44
|
+
Requires-Dist: build>=1.2; extra == "release"
|
|
45
|
+
Requires-Dist: check-wheel-contents>=0.6; extra == "release"
|
|
46
|
+
Requires-Dist: packaging>=24; extra == "release"
|
|
47
|
+
Requires-Dist: pyroma>=4.2; extra == "release"
|
|
48
|
+
Requires-Dist: twine>=6; extra == "release"
|
|
49
|
+
Provides-Extra: dev
|
|
50
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
51
|
+
Requires-Dist: check-wheel-contents>=0.6; extra == "dev"
|
|
52
|
+
Requires-Dist: coverage[toml]>=7.6; extra == "dev"
|
|
53
|
+
Requires-Dist: mypy>=1.14; extra == "dev"
|
|
54
|
+
Requires-Dist: packaging>=24; extra == "dev"
|
|
55
|
+
Requires-Dist: pip-audit>=2.7; extra == "dev"
|
|
56
|
+
Requires-Dist: pyroma>=4.2; extra == "dev"
|
|
57
|
+
Requires-Dist: pytest>=8.3; extra == "dev"
|
|
58
|
+
Requires-Dist: pytest-cov>=6; extra == "dev"
|
|
59
|
+
Requires-Dist: ruff>=0.9; extra == "dev"
|
|
60
|
+
Requires-Dist: tox>=4.23; extra == "dev"
|
|
61
|
+
Requires-Dist: twine>=6; extra == "dev"
|
|
62
|
+
Requires-Dist: yamllint>=1.35; extra == "dev"
|
|
63
|
+
Requires-Dist: zizmor>=1.7; extra == "dev"
|
|
64
|
+
Dynamic: license-file
|
|
65
|
+
|
|
66
|
+
# CTkKanban
|
|
67
|
+
|
|
68
|
+
[](https://github.com/Harry-g25/CTkKanBan/actions/workflows/ci.yml)
|
|
69
|
+
[](https://github.com/Harry-g25/CTkKanBan/actions/workflows/codeql.yml)
|
|
70
|
+
[](https://pypi.org/project/CTkKanBan/)
|
|
71
|
+
[](https://pypi.org/project/CTkKanBan/)
|
|
72
|
+
[](https://github.com/Harry-g25/CTkKanBan/blob/main/LICENSE)
|
|
73
|
+
|
|
74
|
+
CTkKanban is a configurable Kanban widget for CustomTkinter desktop applications. It ships with a polished adaptive light/dark design, live inline card editing, generated forms, drag and drop, search, advanced filters, sorting, undo/redo, responsive columns, and database-backed operation.
|
|
75
|
+
|
|
76
|
+
The built-in design uses layered surfaces, priority-accented cards, responsive metadata tiles, column color rails, active filter treatments, and database status pills. Every visual token remains overridable through `style` or `theme`.
|
|
77
|
+
|
|
78
|
+
## Install
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
python -m pip install CTkKanBan
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## In-memory board
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
import customtkinter as ctk
|
|
88
|
+
import CTkKanBan
|
|
89
|
+
|
|
90
|
+
board_class = CTkKanBan.CTkKanbanBoard
|
|
91
|
+
|
|
92
|
+
app = ctk.CTk()
|
|
93
|
+
board = board_class(
|
|
94
|
+
app,
|
|
95
|
+
columns=[{"id": "todo", "title": "To Do"}, {"id": "done", "title": "Done"}],
|
|
96
|
+
cards=[{"id": 1, "column": "todo", "title": "Try CTkKanban"}],
|
|
97
|
+
completed_columns=["done"],
|
|
98
|
+
)
|
|
99
|
+
board.pack(fill="both", expand=True)
|
|
100
|
+
app.mainloop()
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Inline card editing
|
|
104
|
+
|
|
105
|
+
Inline editing is enabled by default. Click any value rendered on a card—including an empty
|
|
106
|
+
`show_on_card` field—to edit it without opening a dialog. Press Enter or click the check button to
|
|
107
|
+
save, click away to autosave, or press Escape to cancel. Text areas use Ctrl+Enter to save so Enter
|
|
108
|
+
can still insert a new line.
|
|
109
|
+
|
|
110
|
+
Edits use the same validation, callbacks, undo history, filtering, sorting, and persistence path as
|
|
111
|
+
`update_card()`. Read-only and hidden fields are never editable. To keep the earlier popup/side-panel
|
|
112
|
+
interaction, configure `enable_inline_card_editing=False`; `open_edit_card_form(card_id)` also remains
|
|
113
|
+
available for an explicit full-card form.
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
board = CTkKanbanBoard(
|
|
117
|
+
app,
|
|
118
|
+
columns=columns,
|
|
119
|
+
cards=cards,
|
|
120
|
+
fields=fields,
|
|
121
|
+
enable_inline_card_editing=True,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
# Keyboard-free or application-driven activation is also available.
|
|
125
|
+
board.start_inline_card_edit(card_id=1, field_key="priority")
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Automatic field hit targets are available with the default card renderer. Applications using a
|
|
129
|
+
custom `card_renderer` retain the full-card edit flow and can build their own editing controls.
|
|
130
|
+
|
|
131
|
+
## SQLite board
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
import customtkinter as ctk
|
|
135
|
+
from ctk_kanban import CTkKanbanBoard, SQLiteKanbanDataSource
|
|
136
|
+
|
|
137
|
+
app = ctk.CTk()
|
|
138
|
+
source = SQLiteKanbanDataSource("kanban.db")
|
|
139
|
+
source.seed_board("work", [{"id": "todo", "title": "To Do"}], [])
|
|
140
|
+
|
|
141
|
+
board = CTkKanbanBoard(
|
|
142
|
+
app,
|
|
143
|
+
data_source=source,
|
|
144
|
+
board_id="work",
|
|
145
|
+
auto_load=True,
|
|
146
|
+
server_side_query=True,
|
|
147
|
+
poll_interval_ms=2000,
|
|
148
|
+
)
|
|
149
|
+
board.pack(fill="both", expand=True)
|
|
150
|
+
app.mainloop()
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Database work runs outside Tk's UI thread. Mutations carry event, transaction, actor, board, and expected-revision metadata. Adapters may return canonical records with generated IDs, timestamps, versions, and defaults. Failed network writes can be retried or held in the process-local offline queue until connectivity returns.
|
|
154
|
+
|
|
155
|
+
The built-in SQLite adapter provides transactional writes, optimistic revisions, atomic batches, server-side search/filter/sort, paging, change polling, generated IDs, and automatic timestamps. The board shows saving, saved, offline, conflict, and error states; duplicate submissions are blocked while a mutation is pending.
|
|
156
|
+
|
|
157
|
+
For an existing SQL, document, key-value, ORM, or API-backed repository, use
|
|
158
|
+
`CRUDKanbanDataSource` instead of implementing the full adapter contract:
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
from ctk_kanban import CRUDKanbanDataSource
|
|
162
|
+
|
|
163
|
+
source = CRUDKanbanDataSource(
|
|
164
|
+
read=repository.read_board,
|
|
165
|
+
create=repository.create,
|
|
166
|
+
update=repository.update,
|
|
167
|
+
delete=repository.delete,
|
|
168
|
+
transaction=repository.transaction, # Optional
|
|
169
|
+
)
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
The four callbacks receive either `"card"` or `"column"`, the board ID, the record or ID, and a
|
|
173
|
+
`CRUDContext`. The bridge translates moves, reorders, renames, batching, paging, search, filters, and
|
|
174
|
+
canonical generated IDs. This keeps database-specific connection and query code in your application.
|
|
175
|
+
|
|
176
|
+
Use only one durable writer: configure either `data_source` or the legacy `on_data_changed` callback, never both.
|
|
177
|
+
|
|
178
|
+
See the [database integration guide](https://github.com/Harry-g25/CTkKanBan/blob/main/docs/database.md) for the adapter contract, event shape, conflict policies, paging, polling, and a production integration checklist.
|
|
179
|
+
|
|
180
|
+
The example programs are included in the source repository and source distribution, not the installed wheel. From a [source checkout](https://github.com/Harry-g25/CTkKanBan), run `python example_all_features.py` for the UI showcase or `python example_sqlite.py` for the transactional database example.
|
|
181
|
+
|
|
182
|
+
Use `python example_all_features.py --light`, `--dark`, or `--form` to inspect specific appearance and form states. Add `--diagnose` to print the exact package path and version being rendered.
|
|
183
|
+
|
|
184
|
+
## Development
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
python -m pip install -e ".[dev]"
|
|
188
|
+
tox -e lint,type,py314,ctk-min,ctk-current,package
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
CI tests Python 3.10 through 3.14 on Linux and the oldest/latest supported versions on Windows and macOS. It also checks branch coverage, installed-wheel behavior, SQLite persistence, dependency vulnerabilities, package metadata, and workflow security.
|
|
192
|
+
|
|
193
|
+
See the [changelog](https://github.com/Harry-g25/CTkKanBan/blob/main/CHANGELOG.md), [contribution guide](https://github.com/Harry-g25/CTkKanBan/blob/main/CONTRIBUTING.md), [publishing runbook](https://github.com/Harry-g25/CTkKanBan/blob/main/docs/publishing.md), and [project documentation](https://harry-g25.github.io/CTkKanBan/).
|