{"id":13825830,"url":"https://github.com/insolor/async-tkinter-loop","last_synced_at":"2025-04-05T01:05:19.511Z","repository":{"id":37409337,"uuid":"252405300","full_name":"insolor/async-tkinter-loop","owner":"insolor","description":"Asynchronous mainloop implementation for tkinter. Makes it possible to use async functions as event handlers and widget commands.","archived":false,"fork":false,"pushed_at":"2025-03-18T16:56:30.000Z","size":2506,"stargazers_count":80,"open_issues_count":4,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-29T00:06:01.742Z","etag":null,"topics":["aiohttp","asyncio","customtkinter","httpx","tkinter"],"latest_commit_sha":null,"homepage":"https://insolor.github.io/async-tkinter-loop/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/insolor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":null,"custom":"https://www.donationalerts.com/r/insolor"}},"created_at":"2020-04-02T09:01:19.000Z","updated_at":"2025-03-18T16:56:06.000Z","dependencies_parsed_at":"2023-10-03T12:12:29.156Z","dependency_job_id":"9bece4e1-0196-4718-ba36-e59fd4221f19","html_url":"https://github.com/insolor/async-tkinter-loop","commit_stats":{"total_commits":346,"total_committers":4,"mean_commits":86.5,"dds":0.3005780346820809,"last_synced_commit":"84d6d7f3dc7d015832c20b79fc1c5f8e323ebfca"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/insolor%2Fasync-tkinter-loop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/insolor%2Fasync-tkinter-loop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/insolor%2Fasync-tkinter-loop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/insolor%2Fasync-tkinter-loop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/insolor","download_url":"https://codeload.github.com/insolor/async-tkinter-loop/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247271522,"owners_count":20911587,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aiohttp","asyncio","customtkinter","httpx","tkinter"],"created_at":"2024-08-04T09:01:27.718Z","updated_at":"2025-04-05T01:05:19.488Z","avatar_url":"https://github.com/insolor.png","language":"Python","readme":"# Asynchronous Tkinter Mainloop\n\n[![Python tests](https://github.com/insolor/async-tkinter-loop/actions/workflows/python-tests.yml/badge.svg)](https://github.com/insolor/async-tkinter-loop/actions/workflows/python-tests.yml)\n[![Documentation](https://github.com/insolor/async-tkinter-loop/actions/workflows/deploy-docs.yml/badge.svg)](https://insolor.github.io/async-tkinter-loop/)\n[![Coverage Status](https://coveralls.io/repos/github/insolor/async-tkinter-loop/badge.svg?branch=main)](https://coveralls.io/github/insolor/async-tkinter-loop?branch=main)\n[![Maintainability](https://api.codeclimate.com/v1/badges/2566146b14ef72177613/maintainability)](https://codeclimate.com/github/insolor/async-tkinter-loop/maintainability)\n[![PyPI](https://img.shields.io/pypi/v/async-tkinter-loop)](https://pypi.org/project/async-tkinter-loop/)\n![Supported Python versions](https://img.shields.io/pypi/pyversions/async-tkinter-loop)\n\u003c!--![PyPI - Downloads](https://img.shields.io/pypi/dm/async-tkinter-loop)--\u003e\n\nImplementation of asynchronous `mainloop` for tkinter, the use of which allows using `async` handler functions.\nIt is intended to be as simple to use as possible. No fancy unusual syntax or constructions - just use an alternative\nfunction instead of `root.mainloop()` and wrap asynchronous handlers into a helper function.\n\n\u003e **Note**  \n\u003e Please, fill free to [report bugs](https://github.com/insolor/async-tkinter-loop/issues), add [pull requests](https://github.com/insolor/async-tkinter-loop/pulls) or [share your thoughts / ask questions, etc.](https://github.com/insolor/async-tkinter-loop/discussions) about the module.\n\nBased on ideas from:\n\n* my answer on ru.stackoverflow.com: \u003chttps://ru.stackoverflow.com/a/1043146\u003e\n* answer of [Terry Jan Reedy](https://stackoverflow.com/users/722804) on stackoverflow.com:\n  \u003chttps://stackoverflow.com/a/47896365\u003e\n* answer of [jfs](https://ru.stackoverflow.com/users/23044) on ru.stackoverflow.com:\n  \u003chttps://ru.stackoverflow.com/a/804609\u003e\n\n## Installation\n\nInstall the package with the following command:\n\n```\npip install async-tkinter-loop\n```\nor\n```\npip install async-tkinter-loop[examples]\n```\n\n- `[examples]` part is needed to install optional dependencies (such as `httpx` and `pillow`) to run some of the\n  examples. If you're not going to run examples, remove the `[examples]` part from the command\n- Use `pip3` instead of `pip` on Linux systems to install the package for python3 (not python2)\n- Probably you'll want to create a virtual environment for experiments with this library, but this is optional.\n- If you want to try examples, download the entire repository as an archive (green \"code\" button on\n  [the GitHub page](https://github.com/insolor/async-tkinter-loop) →\n  \"Download ZIP\"), unpack, run any example (of course, you need to install optional dependencies)\n\n## Some examples\n\nBasic example:\n```python\nimport asyncio\nimport tkinter as tk\n\nfrom async_tkinter_loop import async_handler, async_mainloop\n\n\nasync def counter():\n    i = 0\n    while True:\n        i += 1\n        label.config(text=str(i))\n        await asyncio.sleep(1.0)\n\n\nroot = tk.Tk()\n\nlabel = tk.Label(root)\nlabel.pack()\n\ntk.Button(root, text=\"Start\", command=async_handler(counter)).pack()\n\nasync_mainloop(root)\n```\n\nAlso, `async_handler` function can be used as a decorator (but it makes a decorated function syncroneous):\n\n```python\nimport asyncio\nimport tkinter as tk\n\nfrom async_tkinter_loop import async_handler, async_mainloop\n\n\n@async_handler\nasync def counter():\n    i = 0\n    while True:\n        i += 1\n        label.config(text=str(i))\n        await asyncio.sleep(1.0)\n\n\nroot = tk.Tk()\n\nlabel = tk.Label(root)\nlabel.pack()\n\ntk.Button(root, text=\"Start\", command=counter).pack()\n\nasync_mainloop(root)\n```\n\nA more practical example, downloading an image from the Internet with [httpx](https://github.com/encode/httpx)\n(you can use [aiohttp](https://github.com/aio-libs/aiohttp) as well)\nand displaying it in the Tkinter window:\n\n```python\nimport tkinter as tk\nfrom io import BytesIO\n\nimport httpx\nfrom PIL import Image, ImageTk\n\nfrom async_tkinter_loop import async_handler, async_mainloop\n\n\nasync def load_image(url):\n    button.config(state=tk.DISABLED)\n    label.config(text=\"Loading...\", image=\"\")\n\n    async with httpx.AsyncClient() as client:\n        response = await client.get(url, follow_redirects=True)\n        if response.status_code != 200:\n            label.config(text=f\"HTTP error {response.status_code}\")\n        else:\n            content = response.content\n            pil_image = Image.open(BytesIO(content))\n            image = ImageTk.PhotoImage(pil_image)\n            label.image = image\n            label.config(image=image, text=\"\")\n            button.config(state=tk.NORMAL)\n\n\nurl = \"https://picsum.photos/800/640\"\n\nroot = tk.Tk()\nroot.geometry(\"800x640\")\n\nbutton = tk.Button(root, text=\"Load an image\", command=async_handler(load_image, url))\nbutton.pack()\n\nlabel = tk.Label(root)\nlabel.pack(expand=1, fill=tk.BOTH)\n\nasync_mainloop(root)\n```\n\nMore examples see in the [`examples`](https://github.com/insolor/async-tkinter-loop/tree/main/examples) directory.\n","funding_links":["https://www.donationalerts.com/r/insolor"],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finsolor%2Fasync-tkinter-loop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finsolor%2Fasync-tkinter-loop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finsolor%2Fasync-tkinter-loop/lists"}