{"id":6843,"library":"qasync","title":"qasync","description":"qasync is a Python library for using asyncio in Qt-based applications, allowing developers to seamlessly integrate asynchronous code into their Qt GUI projects. It is currently at version 0.28.0 and maintains a regular release cadence with updates for new Python versions and performance improvements.","status":"active","version":"0.28.0","language":"en","source_language":"en","source_url":"https://github.com/CabbageDevelopment/qasync","tags":["asyncio","Qt","GUI","asynchronous","PyQt","PySide"],"install":[{"cmd":"pip install qasync","lang":"bash","label":"Install qasync"}],"dependencies":[{"reason":"qasync requires one of the Qt bindings to function.","package":"PyQt5","optional":true},{"reason":"qasync requires one of the Qt bindings to function.","package":"PyQt6","optional":true},{"reason":"qasync requires one of the Qt bindings to function.","package":"PySide2","optional":true},{"reason":"qasync requires one of the Qt bindings to function.","package":"PySide6","optional":true}],"imports":[{"symbol":"QEventLoopPolicy","correct":"from qasync import QEventLoopPolicy"},{"symbol":"asyncSlot","correct":"from qasync import asyncSlot"},{"symbol":"asyncClose","correct":"from qasync import asyncClose"},{"note":"QAsyncApplication is a specialized QApplication that integrates directly with qasync's event loop policy. While QApplication from a Qt binding is used, QAsyncApplication offers deeper integration.","wrong":"from qasync import QApplication","symbol":"QAsyncApplication","correct":"from qasync import QAsyncApplication"}],"quickstart":{"code":"import asyncio\nimport sys\n\n# Choose your Qt binding: PyQt5, PyQt6, PySide2, PySide6\n# For this example, we'll use PyQt5\nfrom PyQt5.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget, QPushButton\n\nfrom qasync import QEventLoopPolicy, asyncSlot\n\nasync def long_running_task(duration_seconds: int = 2):\n    \"\"\"A mock asynchronous task.\"\"\"\n    print(f\"[Task] Starting long-running task for {duration_seconds} seconds...\")\n    await asyncio.sleep(duration_seconds)\n    print(\"[Task] Long-running task finished!\")\n    return \"Task Completed!\"\n\nclass MainWindow(QWidget):\n    def __init__(self):\n        super().__init__()\n        self.setWindowTitle(\"qasync Quickstart Demo\")\n        self.setGeometry(100, 100, 400, 200)\n\n        self.layout = QVBoxLayout()\n        self.label = QLabel(\"Click the button to start an async task.\")\n        self.button = QPushButton(\"Run Async Task\")\n\n        # Connect a Qt signal to an asynchronous slot using @asyncSlot\n        self.button.clicked.connect(self.run_task)\n\n        self.layout.addWidget(self.label)\n        self.layout.addWidget(self.button)\n        self.setLayout(self.layout)\n\n    @asyncSlot()\n    async def run_task(self):\n        \"\"\"This slot runs an async task without blocking the GUI.\"\"\"\n        self.label.setText(\"Task started, please wait...\")\n        self.button.setEnabled(False) # Disable button while task is running\n\n        result = await long_running_task(3) # Await the async task\n        \n        self.label.setText(f\"Result: {result}\")\n        self.button.setEnabled(True) # Re-enable button\n\nif __name__ == \"__main__\":\n    # IMPORTANT: Set the asyncio event loop policy *before* creating QApplication\n    asyncio.set_event_loop_policy(QEventLoopPolicy())\n\n    app = QApplication(sys.argv)\n    window = MainWindow()\n    window.show()\n    \n    # Run the Qt application\n    sys.exit(app.exec_())\n","lang":"python","description":"This quickstart demonstrates how to integrate `asyncio` with a basic Qt application using `qasync`. It shows how to set the `QEventLoopPolicy`, create an `asyncSlot` for a button click, and run an `asyncio` task without blocking the GUI."},"warnings":[{"fix":"Upgrade your Python environment to 3.8 or a later compatible version.","message":"Support for Python 3.6 and Python 3.7 was dropped starting with version 0.25.0. Ensure your project is using Python 3.8 or newer.","severity":"breaking","affected_versions":">=0.25.0"},{"fix":"Run `pip install PyQt5` (or your preferred binding) in addition to `pip install qasync`.","message":"qasync does not automatically install a Qt binding. You must explicitly install one (e.g., PyQt5, PyQt6, PySide2, or PySide6) in your environment for qasync to function.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Upgrade to qasync 0.27.1 or newer: `pip install --upgrade qasync`.","message":"Version 0.27.0 was released with a critical bug. It is strongly recommended to use version 0.27.1 or any later version instead.","severity":"deprecated","affected_versions":"0.27.0"},{"fix":"Place `asyncio.set_event_loop_policy(QEventLoopPolicy())` at the very beginning of your application's `if __name__ == '__main__':` block, before any `QApplication` initialization.","message":"The `asyncio.set_event_loop_policy(QEventLoopPolicy())` call MUST be made before instantiating the `QApplication` (or `QAsyncApplication`) object. Failing to do so will result in `asyncio` not being properly integrated with Qt's event loop, leading to unexpected behavior or errors.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Decorate your async functions that act as signal slots with `@asyncSlot()`. Example: `@asyncSlot()\nasync def my_async_slot(): ...`","message":"When connecting an asynchronous Python function (a coroutine) to a Qt signal, you must wrap it with the `@asyncSlot()` decorator. Connecting async functions directly without this decorator will raise a `TypeError`.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-15T00:00:00.000Z","next_check":"2026-07-14T00:00:00.000Z","problems":[]}