Python library for using asyncio in Qt-based applications
npx @tessl/cli install tessl/pypi-qasync@0.28.00
# qasync
1
2
Python library for using asyncio in Qt-based applications, providing an implementation of the PEP 3156 event loop that enables coroutines and asyncio functionality to run directly inside Qt application event loops in the main thread.
3
4
## Package Information
5
6
- **Package Name**: qasync
7
- **Language**: Python
8
- **Installation**: `pip install qasync`
9
- **Qt Framework Support**: PyQt5, PyQt6, PySide2, PySide6
10
- **Python Requirements**: Python >=3.8, <3.14
11
12
## Core Imports
13
14
```python
15
import qasync
16
```
17
18
Common usage patterns:
19
20
```python
21
from qasync import QApplication, QEventLoop, QThreadExecutor, asyncSlot, asyncClose, asyncWrap
22
```
23
24
## Basic Usage
25
26
```python
27
import asyncio
28
import sys
29
from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel
30
31
from qasync import QApplication, QEventLoop, asyncSlot, asyncClose
32
33
class MainWindow(QWidget):
34
def __init__(self):
35
super().__init__()
36
self.setLayout(QVBoxLayout())
37
self.lbl_status = QLabel("Idle", self)
38
self.layout().addWidget(self.lbl_status)
39
40
@asyncClose
41
async def closeEvent(self, event):
42
# Run async cleanup before app closes
43
await asyncio.sleep(0.1) # Example async operation
44
45
@asyncSlot()
46
async def on_button_clicked(self):
47
# Handle button click asynchronously
48
self.lbl_status.setText("Processing...")
49
await asyncio.sleep(2) # Simulate async work
50
self.lbl_status.setText("Complete!")
51
52
if __name__ == "__main__":
53
app = QApplication(sys.argv)
54
55
app_close_event = asyncio.Event()
56
app.aboutToQuit.connect(app_close_event.set)
57
58
main_window = MainWindow()
59
main_window.show()
60
61
# Python 3.12+ syntax
62
asyncio.run(app_close_event.wait(), loop_factory=QEventLoop)
63
64
# For Python 3.11 and older
65
# qasync.run(app_close_event.wait())
66
```
67
68
## Architecture
69
70
qasync bridges Python's asyncio ecosystem with Qt's event-driven architecture through several key components:
71
72
- **QEventLoop**: Custom asyncio event loop that integrates with Qt's QApplication event loop
73
- **Platform Integration**: Automatic detection and support for PyQt5/6 and PySide2/6 frameworks
74
- **Thread Execution**: QThreadExecutor provides concurrent.futures-compatible thread pool using QThread
75
- **Decorators**: @asyncSlot and @asyncClose enable seamless async integration with Qt's signal-slot system
76
- **Cross-Platform**: Platform-specific implementations for Unix (selector-based) and Windows (IOCP-based) I/O
77
78
The library automatically detects the available Qt framework (PyQt5, PyQt6, PySide2, or PySide6) and adapts accordingly, making it framework-agnostic while maintaining full asyncio compatibility.
79
80
## Capabilities
81
82
### Qt Application Integration
83
84
Framework-agnostic QApplication that automatically detects and adapts to available Qt frameworks (PyQt5, PyQt6, PySide2, PySide6), providing a unified interface for Qt application initialization.
85
86
```python { .api }
87
class QApplication:
88
"""
89
Qt Application class that automatically adapts to the available Qt framework.
90
91
Provides the same interface as Qt's QApplication but automatically detects
92
and uses the correct implementation from PyQt5/6 or PySide2/6.
93
"""
94
def __init__(self, args=None): ...
95
def exec(self): ... # PyQt6/PySide6
96
def exec_(self): ... # PyQt5/PySide2
97
def aboutToQuit: ... # Signal
98
def instance(self): ... # Class method
99
def processEvents(self): ...
100
```
101
102
### Event Loop Integration
103
104
Qt-compatible asyncio event loop that runs coroutines alongside Qt's native event processing, enabling responsive GUI applications with asynchronous operations.
105
106
```python { .api }
107
class QEventLoop:
108
def __init__(app=None, set_running_loop=False, already_running=False): ...
109
def run_forever(): ...
110
def run_until_complete(future): ...
111
def stop(): ...
112
def close(): ...
113
```
114
115
[Event Loop Integration](./event-loop.md)
116
117
### Thread Execution
118
119
Thread pool executor using Qt's QThread for CPU-intensive tasks, providing concurrent.futures.Executor-compatible interface for parallel processing.
120
121
```python { .api }
122
class QThreadExecutor:
123
def __init__(max_workers=10, stack_size=None): ...
124
def submit(callback, *args, **kwargs): ...
125
def shutdown(wait=True): ...
126
```
127
128
[Thread Execution](./thread-executor.md)
129
130
### Async Decorators
131
132
Decorators that enable Qt slots and event handlers to run as async coroutines, integrating asyncio seamlessly with Qt's signal-slot system.
133
134
```python { .api }
135
def asyncSlot(*args, **kwargs): ...
136
def asyncClose(fn): ...
137
```
138
139
[Async Decorators](./async-decorators.md)
140
141
### Utility Functions
142
143
Helper functions for wrapping blocking operations and running asyncio with Qt event loops, plus advanced event loop policy classes.
144
145
```python { .api }
146
async def asyncWrap(fn, *args, **kwargs): ...
147
def run(*args, **kwargs): ...
148
class DefaultQEventLoopPolicy: ...
149
```
150
151
[Utility Functions](./utilities.md)