Async library for Tkinter
Project description
AsyncTkinter2
asynctkinter2 はtkinter用のライブラリで、 よくあるasyncライブラリと同じでコールバック関数だらけの醜いコードを読みやすくしてくれます。 例えば
- Aを出力
- 一秒待機
- Bを出力
- labelが押されるまで待機
- Cを出力
といった事を普通にやろうとするとコードは
def やりたき事(label):
bind_id = None
print('A')
def 一秒後に(__):
nonlocal bind_id
print('B')
bind_id = label.bind("<ButtonPress>", labelが押された時に, "+")
label.after(1000, 一秒後に)
def labelが押された時に(event):
label.unbind("<ButtonPress>", bind_id)
print('C')
やりたき事(...)
のように読みにくい物となりますがasynctkinter2を用いることで
import asynctkinter2 as atk
async def やりたき事(label):
print('A')
await atk.sleep(label, 1000)
print('B')
await atk.event(label, "<ButtonPress>")
print('C')
atk.start(やりたき事(...))
と分かりやすく書けます。
Installation
Pin the minor version.
pip install "asynctkinter2>=0.1,<0.2"
使用例
import tkinter as tk
import asynctkinter2 as atk
def main():
root = tk.Tk()
root_task = atk.start(async_main(root))
root.protocol("WM_DELETE_WINDOW", lambda: (root_task.cancel(), root.destroy()))
root.mainloop()
async def async_main(root: tk.Tk):
label = tk.Label(root, text='Hello', font=('', 80))
label.pack()
# 二秒待つ
await atk.sleep(root, 2000)
# labelが押されるのを待つ
event = await atk.event(label, "<ButtonPress>")
print(f"pos: {event.x}, {event.y}")
# labelが押される か 5秒経つまで待つ。
tasks = await atk.wait_any(
atk.sleep(root, 5000),
atk.event(label, "<ButtonPress>"),
)
if tasks[0].finished:
print("5秒経った")
else:
event = tasks[1].result
print(f"labelが押された (pos: {event.x}, {event.y})")
# labelが押され なおかつ 5秒経つまで待つ
tasks = await atk.wait_all(
atk.sleep(root, 5000),
atk.event(label, "<ButtonPress>"),
)
# GUIを固まらせずにHTTPリクエストを実行し、その完了を待つ
import requests
res: requests.Response = await atk.run_in_thread(root, lambda: requests.get("https://httpbin.org/delay/2"))
label["text"] = f"{res.status_code = }"
if __name__ == "__main__":
main()
asynctkinter との違い
現在のasynctkinterは
- メインループは
tkinterが元々持っているmainloop()ではなく独自の物を用い - タイマー機能に関しても
tkinterが元々持っているafter()ではなく独自の物を用いています。
対して asynctkinter2 では独自の物を用いないようにしています。
そのおかげで asyncio や trio といった他のasyncライブラリと共存しやくなっています。
ただ代償としてフレームレート非依存のアニメーションを書く際の手間が増えます。
具体的には自身で time.perf_counter() 等を用いて経過時間を計測しないといけません。
asyncio との共存
共存といっても何でもできるわけではなく、1つのasync関数内に asyncio に対するasync処理とasynctkinter2 に対するasync処理を混在させることはできません。
async def this_does_not_work():
await asyncio.sleep(1)
await asynctkinter2.sleep(widget, 1000)
ここで言う "async処理" というのは予約語の async や await を含む処理だけを指します。
なので以下のコードでは asyncio に対する処理と asynctkinter2 に対する処理が混在しているものの、asynctkinter2 側は予約語 async/await を含んでいないため問題ありません。
async def this_works():
await asyncio.sleep(1)
task = asynctkinter2.start(...)
asyncio.create_task(this_works())
以下の例も asyncio 側がasync処理ではないので問題ありません。
async def this_also_works():
task = asyncio.create_task(...)
await asynctkinter2.sleep(widget, 1000)
asynctkinter2.start(this_also_works())
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file asynctkinter2-0.1.1.tar.gz.
File metadata
- Download URL: asynctkinter2-0.1.1.tar.gz
- Upload date:
- Size: 4.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ca31e2c0d04d50c1be14176e02c4aa0220ebece0c7e6b586ccb54b82e82defa
|
|
| MD5 |
a8231fa8b403384a26d136cc732da714
|
|
| BLAKE2b-256 |
292e82ebce9500a301027fb5213e78ff9d7377b98f8801ed58d3e9b0a0b43e42
|
Provenance
The following attestation bundles were made for asynctkinter2-0.1.1.tar.gz:
Publisher:
release.yml on asyncgui/asynctkinter2
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
asynctkinter2-0.1.1.tar.gz -
Subject digest:
4ca31e2c0d04d50c1be14176e02c4aa0220ebece0c7e6b586ccb54b82e82defa - Sigstore transparency entry: 1395919822
- Sigstore integration time:
-
Permalink:
asyncgui/asynctkinter2@7cb15988d6dc3a381d3e5620a82ec4e38445383b -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/asyncgui
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7cb15988d6dc3a381d3e5620a82ec4e38445383b -
Trigger Event:
push
-
Statement type:
File details
Details for the file asynctkinter2-0.1.1-py3-none-any.whl.
File metadata
- Download URL: asynctkinter2-0.1.1-py3-none-any.whl
- Upload date:
- Size: 5.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0bb345d9532aae0b26e28a7f3af697ccd507905a5ce7e001a2d8ea3497035618
|
|
| MD5 |
44848c895d80bf325d04fcdcea7650e2
|
|
| BLAKE2b-256 |
9e8e7fc7cc1a7edc8c320b334a71634d44cc8fe573f12588d21bc99d07470b05
|
Provenance
The following attestation bundles were made for asynctkinter2-0.1.1-py3-none-any.whl:
Publisher:
release.yml on asyncgui/asynctkinter2
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
asynctkinter2-0.1.1-py3-none-any.whl -
Subject digest:
0bb345d9532aae0b26e28a7f3af697ccd507905a5ce7e001a2d8ea3497035618 - Sigstore transparency entry: 1395919827
- Sigstore integration time:
-
Permalink:
asyncgui/asynctkinter2@7cb15988d6dc3a381d3e5620a82ec4e38445383b -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/asyncgui
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7cb15988d6dc3a381d3e5620a82ec4e38445383b -
Trigger Event:
push
-
Statement type: