Skip to main content

AsyncTkinter

Youtube

asynctkinter is an async library that saves you from ugly callback-style code, like most of async libraries do. Let's say you want to do:

  1. print('A')
  2. wait for 1sec
  3. print('B')
  4. wait for a label to be pressed
  5. print('C')

in that order. Your code would look like this:

def what_you_want_to_do(label):
    bind_id = None
    print('A')

    def one_sec_later(__):
        nonlocal bind_id
        print("B")
        bind_id = label.bind("<ButtonPress>", on_press, "+")
    label.after(1000, one_sec_later)

    def on_press(event):
        label.unbind("<ButtonPress>", bind_id)
        print("C")

what_you_want_to_do(...)

It's not easy to understand. If you use asynctkinter, the code above will become:

import asynctkinter as atk

async def what_you_want_to_do(clock, label):
    print("A")
    await clock.sleep(1)
    print("B")
    await atk.event(label, "<ButtonPress>")
    print("C")

atk.start(what_you_want_to_do(...))

Installation

Pin the minor version.

pip install "asynctkinter>=0.5,<0.6"

Usage

import tkinter as tk
import asynctkinter as atk


async def main(*, clock: atk.Clock, root: tk.Tk):
    label = tk.Label(root, text='Hello', font=('', 80))
    label.pack()

    # waits for 2 seconds to elapse
    await clock.sleep(2)

    # waits for a label to be pressed
    event = await atk.event(label, "<ButtonPress>")
    print(f"pos: {event.x}, {event.y}")

    # waits for either 5 seconds to elapse or a label to be pressed.
    # i.e. waits at most 5 seconds for a label to be pressed
    tasks = await atk.wait_any(
        clock.sleep(5),
        atk.event(label, "<ButtonPress>"),
    )
    if tasks[0].finished:
        print("Timeout")
    else:
        event = tasks[1].result
        print(f"The label got pressed. (pos: {event.x}, {event.y})")

    # same as the above
    async with clock.move_on_after(5) as timeout_tracker:
        event = await atk.event(label, "<ButtonPress>")
        print(f"The label got pressed. (pos: {event.x}, {event.y})")
    if timeout_tracker.finished:
        print("Timeout")

    # waits for both 5 seconds to elapse and a label to be pressed.
    tasks = await atk.wait_all(
        clock.sleep(5),
        atk.event(label, "<ButtonPress>"),
    )

    # nests as you want.
    tasks = await ak.wait_all(
        atk.event(label, "<ButtonPress>"),
        atk.wait_any(
            clock.sleep(5),
            ...,
        ),
    )
    child_tasks = tasks[1].result


if __name__ == "__main__":
    atk.run(main)

threading

Unlike trio and asyncio, asynckivy does not provide any I/O primitives. Therefore, if you don’t want to implement your own, using threads may be the best way to perform I/O without blocking the main thread.

from concurrent.futures import ThreadPoolExecuter
import asynctkinter as atk

executer = ThreadPoolExecuter()

async def async_fn(clock: atk.Clock):
    # create a new thread, run a function inside it, then
    # wait for the completion of that thread
    r = await atk.run_in_thread(clock, thread_blocking_operation)
    print("return value:", r)

    # run a function inside a ThreadPoolExecuter, and wait for its completion.
    # (ProcessPoolExecuter is not supported)
    r = await atk.run_in_executer(clock, executer, thread_blocking_operation)
    print("return value:", r)

Unhandled exceptions (excluding BaseException that is not Exception) are propagated to the caller so you can catch them like you do in synchronous code:

import requests
import asynctkinter as atk

async def async_fn(clock: atk.Clock):
    try:
        r = await atk.run_in_thread(clock, lambda: requests.get('htt...', timeout=10), ...)
    except requests.Timeout:
        print("TIMEOUT!")
    else:
        print('RECEIVED:', r)

Notes

Release files for asynctkinter 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for asynctkinter 0.5.0
File Size Uploaded
asynctkinter-0.5.0.tar.gz 4.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for asynctkinter 0.5.0
File Interpreter ABI Platform
asynctkinter-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 10.1 kB

Release files / asynctkinter-0.5.0.tar.gz

Download URL asynctkinter-0.5.0.tar.gz
Size 4.6 kB
Tags Source
SHA-256 checksum
How to use checksums
5d549b3129bbcf308598782f69fbd43a687eb58685c7a84241858ba658cec875
BLAKE2b-256 checksum
How to use checksums
827b3d5a17fc69a712c843a4b9a904e1290e719bea3377fa45b59143d73a82ba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 May 1, 2026.

Transparency log

Release files / asynctkinter-0.5.0-py3-none-any.whl

Download URL asynctkinter-0.5.0-py3-none-any.whl
Size 5.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
273e53257e784a575c7034219b9706650d447b2e7767ddf02f8b213b19183907
BLAKE2b-256 checksum
How to use checksums
ea34cedad76d1bc584112c6a521ce2653c2e7b5b4b12502b6a50f96186df9d34
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 May 1, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.5.0 This release

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page