or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-decorators.mdevent-loop.mdindex.mdthread-executor.mdutilities.md

index.mddocs/

0

# 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)