Skip to main content

async library for tkinter

Project description

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('<Button>', on_press, '+')
    label.after(1000, one_sec_later)

    def on_press(event):
        label.unbind('<Button>', 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 at

async def what_you_want_to_do(clock, label):
    print('A')
    await clock.sleep(1)
    print('B')
    await at.event(label, '<Button>')
    print('C')

at.start(what_you_want_to_do(...))

Installation

Pin the minor version.

poetry add asynctkinter@~0.4
pip install "asynctkinter>=0.4,<0.5"

Usage

import tkinter as tk
import asynctkinter as at


async def main(*, clock: at.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 at.event(label, '<Button>')
    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 at.wait_any(
        clock.sleep(5),
        at.event(label, '<Button>'),
    )
    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 at.event(label, '<Button>')
        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 at.wait_all(
        clock.sleep(5),
        at.event(label, '<Button>'),
    )

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


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

threading

Unlike Trio and asyncio, asynctkinter doesn't provide any I/O functionalities, thus threads may be the best way to perform them without blocking the main thread:

from concurrent.futures import ThreadPoolExecuter
import asynctkinter as at

executer = ThreadPoolExecuter()

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

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

Exceptions(not BaseExceptions) are propagated to the caller, so you can catch them like you do in synchronous code:

import requests
import asynctkinter as at

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

Notes

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

asynctkinter-0.4.1.tar.gz (4.3 kB view details)

Uploaded Source

Built Distribution

asynctkinter-0.4.1-py3-none-any.whl (4.9 kB view details)

Uploaded Python 3

File details

Details for the file asynctkinter-0.4.1.tar.gz.

File metadata

  • Download URL: asynctkinter-0.4.1.tar.gz
  • Upload date:
  • Size: 4.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.5.1 CPython/3.11.4 Linux/5.4.0-186-generic

File hashes

Hashes for asynctkinter-0.4.1.tar.gz
Algorithm Hash digest
SHA256 d08a86cd554b5c373b30c70c7b188e5d92e6bdd4536a0c815ecf0d1590d2b5b0
MD5 55d8f758a2fbec940793be06fa305ec6
BLAKE2b-256 c6a3a29d69a0010a5afc9efd6b8f4ed85ded2590ea031a4e93414c3a29eb4b96

See more details on using hashes here.

File details

Details for the file asynctkinter-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: asynctkinter-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 4.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.5.1 CPython/3.11.4 Linux/5.4.0-186-generic

File hashes

Hashes for asynctkinter-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2e235846dca137e724920636e8ce83a29b2c50aff1715eed7692c88f05ecb8dc
MD5 fe9231fe5b896ecf84fe7f974fd07bfb
BLAKE2b-256 ad62b25c37b0f13f75d7139223814446db87c1cf4ecbe978dcd9af3b58877a8e

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page