tk-uia
Make Tkinter applications fully accessible to Windows screen readers and UI Automation: named, correctly typed, and activatable.
Tk 8.6 exposes widgets to Windows accessibility with no names and mostly wrong
control types: buttons are unnamed, labels read as images, and every themed
ttk widget is an anonymous pane. tk_uia.enable(root) fixes both halves.
Each widget is annotated through MSAA for legacy clients, and answers UI
Automation for itself: Invoke genuinely presses, Value genuinely types,
Toggle, SelectionItem and RangeValue genuinely act, and names and states
are read live from the widget at the moment a client asks. Screen readers such
as NVDA, and UIA tools such as Inspect.exe or
pytest-uia, see controls they can both
read and operate. No runtime dependencies, no C extension, no visible change
to the window.
Install
pip install tk-uia
Windows only. On other platforms enable() returns UNSUPPORTED and does
nothing, so cross-platform code can call it unconditionally.
Usage
import tkinter as tk
import tk_uia
root = tk.Tk()
root.title("Tasks")
tk.Label(root, text="Task list").pack()
tk.Button(root, text="New Task", command=create).pack()
tk_uia.enable(root)
root.mainloop()
enable() comes first: every other call (set_acc_name, label_for, the
bind_* family) refuses until it has run.
| Widget | Bare Tk | After enable() |
|---|---|---|
tk.Button(text="New Task") |
ButtonControl, no name, Invoke does nothing |
ButtonControl, Name='New Task', Invoke presses it |
tk.Label(text="Task list") |
ImageControl, no name |
TextControl, name read live |
tk.Checkbutton(text="Done") |
ButtonControl, no name |
CheckBoxControl, Toggle works, live ToggleState |
tk.Entry(textvariable=var) |
PaneControl, no ValuePattern |
EditControl, SetValue types into it |
ttk.Button(text="Save") |
anonymous PaneControl |
ButtonControl, named, Invoke presses it |
tk.Scale(from_=0, to=10) |
PaneControl |
SliderControl, RangeValue moves it |
Measured from a separate process. COVERAGE.md has the table for every widget class in both toolkits. COOKBOOK.md builds a real form end to end.
Features
- One call covers the whole application, including windows opened later.
- Working patterns per class:
Invokefor buttons,Togglefor checkbuttons,SelectionItemfor radiobuttons and notebook tabs,Valuefor entries, spinboxes, comboboxes andText,RangeValuefor scales and progressbars. - Names, values, enabled state, help and description are pulled live at the moment a client asks; name and value changes are raised as UIA property-changed events.
- Names inferred from
-text, correct control types for classictkandttk. - A declared
textvariableis followed automatically: the name or value stays current with no further code. label_for(label, entry)records which caption names which field.infer_names_from_layout(root)retrofits an existing dialog in one call and reports every name it chose.describe(root)returns an audit you canprint(): what a client gets and what is missing, with a reason and a fix per widget. Usable as data for CI gating.- Notebook tabs become real tab controls a client can switch without a click.
annotate_only(root)keeps the previous annotation-only behaviour, andleave_to_the_proxy(widget)opts a single widget out.- Detects Tk 9.1's native accessibility (TIP 733) and stands down.
Limitations
- In-process only. You can make your own application accessible, not someone else's.
- Listbox rows and Treeview items are not exposed. Notebook tabs are.
- A combobox has no ExpandCollapse yet, so a client cannot open its dropdown;
choosing goes through
ValuePattern.SetValue, which on a readonly combobox takes exactly the values a user could pick and fires the same<<ComboboxSelected>>a dropdown choice would. infer_names_from_layoutis a guess by convention: rows are frames, or grid rows within a frame, read across their columns. It returns every name it chose; read the guess before shipping it.- A widget left to the MSAA proxy advertises an
InvokePatternthat does nothing; that is the proxy's own behaviour, anddescribe()says which widgets it applies to. - Verified against the UI Automation tree, which is what screen readers consume. Not yet verified against NVDA speech output; that is what 1.0 means on the roadmap.
Documentation
| COOKBOOK.md | Your first accessible form, in ten minutes. |
| docs/GUIDE.md | Full API, how it works, every caveat and measurement. |
| COVERAGE.md | Every widget class, measured bare and after enable(). |
| ROADMAP.md | What is next and what is out of scope. |
| CHANGELOG.md | Release history. |
License
Release files for tk-uia 0.7.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tk_uia-0.7.0.tar.gz | 177.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tk_uia-0.7.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 234.6 kB
Release files / tk_uia-0.7.0.tar.gz
| Download URL | tk_uia-0.7.0.tar.gz |
|---|---|
| Size | 177.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
83561fbde6a6409d072a886a18a07655aa4f714ffc9656b3aea9675d30f74a04
|
|
BLAKE2b-256 checksum How to use checksums |
404556c7e2e8c5d3a8d0516cda19ed5ac2f0d5285213fceaaa2df49ff3f67fbe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 28, 2026.
Transparency logRelease files / tk_uia-0.7.0-py3-none-any.whl
| Download URL | tk_uia-0.7.0-py3-none-any.whl |
|---|---|
| Size | 57.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c5db5cca7012f17304e2cccf3a645050d4ecc16a2721790007c5597404769291
|
|
BLAKE2b-256 checksum How to use checksums |
97dd6222b98659011b82f1baf3e0b99fa3746c0d9f62d7a1305be9b7d119b490
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 28, 2026.
Transparency log