{"id":16607516,"url":"https://github.com/qcoro/qcoro","last_synced_at":"2026-02-14T01:06:31.592Z","repository":{"id":37077081,"uuid":"351158023","full_name":"qcoro/qcoro","owner":"qcoro","description":"C++ Coroutines for Qt","archived":false,"fork":false,"pushed_at":"2026-02-12T08:25:57.000Z","size":1365,"stargazers_count":537,"open_issues_count":38,"forks_count":78,"subscribers_count":16,"default_branch":"main","last_synced_at":"2026-02-12T17:42:34.464Z","etag":null,"topics":["async","coroutines","cpp","cpp20","qt","qt5","qt6"],"latest_commit_sha":null,"homepage":"https://qcoro.dev","language":"C++","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/qcoro.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["danvratil"],"liberapay":"dvratil","ko_fi":"dvratil","custom":["https://paypal.me/dvratil"]}},"created_at":"2021-03-24T16:56:23.000Z","updated_at":"2026-02-12T08:26:02.000Z","dependencies_parsed_at":"2023-10-10T15:16:21.281Z","dependency_job_id":"fe3fa97a-6833-4cda-8703-8bfec4e22fc3","html_url":"https://github.com/qcoro/qcoro","commit_stats":{"total_commits":542,"total_committers":26,"mean_commits":"20.846153846153847","dds":0.1531365313653137,"last_synced_commit":"da13d8646a56c2aa75f76544a474a07181357468"},"previous_names":["qcoro/qcoro"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/qcoro/qcoro","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qcoro%2Fqcoro","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qcoro%2Fqcoro/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qcoro%2Fqcoro/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qcoro%2Fqcoro/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/qcoro","download_url":"https://codeload.github.com/qcoro/qcoro/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qcoro%2Fqcoro/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29427779,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-13T22:20:51.549Z","status":"ssl_error","status_checked_at":"2026-02-13T22:20:49.838Z","response_time":78,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["async","coroutines","cpp","cpp20","qt","qt5","qt6"],"created_at":"2024-10-12T01:20:54.130Z","updated_at":"2026-02-14T01:06:31.572Z","avatar_url":"https://github.com/qcoro.png","language":"C++","readme":"[![Linux CI](https://github.com/qcoro/qcoro/actions/workflows/build-linux.yml/badge.svg)](https://github.com/qcoro/qcoro/actions/workflows/build-linux.yml)\n[![Windows CI](https://github.com/qcoro/qcoro/actions/workflows/build-windows.yml/badge.svg)](https://github.com/qcoro/qcoro/actions/workflows/build-windows.yml)\n[![MacOS CI](https://github.com/qcoro/qcoro/actions/workflows/build-macos.yml/badge.svg)](https://github.com/qcoro/qcoro/actions/workflows/build-macos.yml)\n[![Docs build](https://github.com/qcoro/qcoro/actions/workflows/update-docs.yml/badge.svg?branch=main)](https://github.com/qcoro/qcoro/actions/workflows/update-docs.yml)\n[![Latest release](https://img.shields.io/github/v/release/qcoro/qcoro?label=%F0%9F%93%A6%20Release)](https://github.com/qcoro/qcoro/releases)\n![License: MIT](https://img.shields.io/badge/%E2%9A%96%EF%B8%8F%20License-MIT-brightgreen)\n![C++20](https://img.shields.io/badge/C%2B%2B-20-%2300599C?logo=cplusplus)\n![Supported Compilers](https://img.shields.io/badge/%E2%9A%99%EF%B8%8F%20Compilers-GCC%2C%20clang%2C%20MSVC-informational)\n\n# QCoro - Coroutines for Qt5 and Qt6\n\nThe QCoro library provides set of tools to make use of C++20 coroutines with Qt.\n\nTake a look at the example below to see what an amazing thing coroutines are:\n```cpp\nQNetworkAccessManager networkAccessManager;\n// co_await the reply - the coroutine is suspended until the QNetworkReply is finished.\n// While the coroutine is suspended, *the Qt event loop runs as usual*.\nconst QNetworkReply *reply = co_await networkAccessManager.get(url);\n// Once the reply is finished, your code resumes here as if nothing amazing has just happened ;-)\nconst auto data = reply-\u003ereadAll();\n```\n\nIt requires a compiler with support for the couroutines TS, see [documentation](https://qcoro.dev/#supported-compilers) for a list of supported compilers and versions.\n\n## Documentation\n\n👉 📘 [Documentation](https://qcoro.dev/)\n\n## Supported Qt Types\n\nQCoro provides the tools necessary to make easy use of C++20 coroutines with Qt. The cornerstone of\nthe library is `QCoro::Task\u003cT\u003e`, which represents an executed coroutine and allows the result of\nthe coroutine to be asynchronously awaited by its caller. Additionally, QCoro provides a set of\nwrappers for common Qt types, such as `QTimer`, `QNetworkReply`, `QDBusPendingCall`, `QFuture`\nand others, that allow to `co_await` their asynchronous operations directly.\n\nAdditionally, there's a magical `qCoro()` function that can wrap many native Qt functions and types\nto make them coroutine-friendly.\n\nGo check the [documentation](https://qcoro.dev/reference) for a full list of all supported\nfeatures and Qt types.\n\n### `QDBusPendingCall`\n\nQCoro can wait for an asynchronous D-Bus call to finish. There's no need to use `QDBusPendingCallWatcher`\nwith QCoro - just `co_await` the result instead. While co_awaiting, the Qt event loop runs as usual.\n\n```cpp\nQDBusInterface remoteServiceInterface{serviceName, objectPath, interface};\nconst QDBusReply\u003cbool\u003e isReady = co_await remoteServiceInterface.asyncCall(QStringLiteral(\"isReady\"));\n```\n\n📘 [Full documentation here](https://qcoro.dev/reference/dbus/qdbuspendingcall).\n\n### `QFuture`\n\nQFuture represents a result of an asynchronous task. Normally you have to use `QFutureWatcher` to get\nnotified when the future is ready. With QCoro, you can just `co_await` it!\n\n```cpp\nconst QFuture\u003cint\u003e task1 = QtConcurrent::run(....);\nconst QFuture\u003cint\u003e task2 = QtConcurrent::run(....);\n\nconst int a = co_await task1;\nconst int b = co_await task2;\n\nco_return a + b;\n```\n\n📘 [Full documentation here](https://qcoro.dev/reference/core/qfuture).\n\n### `QNetworkReply`\n\nDoing network requests with Qt can be tedious - the signal/slot approach breaks the flow\nof your code. Chaining requests and error handling quickly become mess and your code is\nbroken into numerous functions. But not with QCoro, where you can simply `co_await` the\n`QNetworkReply` to finish:\n\n```cpp\nQNetworkAccessManager qnam;\nQNetworkReply *reply = qnam.get(QStringLiteral(\"https://github.com/qcoro/qcoro\"));\nconst auto contents = co_await reply;\nreply-\u003edeleteLater();\nif (reply-\u003eerror() != QNetworkReply::NoError) {\n    co_return handleError(reply);\n}\n\nconst auto link = findLinkInReturnedHtmlCode(contents);\nreply = qnam.get(link);\nconst auto data = co_await reply;\nreply-\u003edeleteLater();\nif (reply-\u003eerror() != QNetworkReply::NoError) {\n    co_return handleError(reply);\n}\n ...\n ```\n\n📘 [Full documentation here](https://qcoro.dev/reference/network/qnetworkreply).\n\n### `QTimer`\n\nMaybe you want to delay executing your code for a second, maybe you want to execute some\ncode in repeated interval. This becomes super-trivial with `co_await`:\n\n```cpp\nQTimer timer;\ntimer.setInterval(1s);\ntimer.start();\n\nfor (int i = 1; i \u003c= 100; ++i) {\n    co_await timer;\n    qDebug() \u003c\u003c \"Waiting for \" \u003c\u003c i \u003c\u003c \" seconds...\";\n}\n\nqDebug() \u003c\u003c \"Done!\";\n```\n\n📘 [Full documentation here](https://qcoro.dev/reference/core/qtimer).\n\n### `QIODevice`\n\n`QIODevice` is a base-class for many classes in Qt that allow data to be asynchronously\nwritten and read. How do you find out that there are data ready to be read? You could\nconnect to `QIODevice::readyRead()` singal, or you could use QCoro and `co_await` the object:\n\n```cpp\nsocket-\u003ewrite(\"PING\");\n// Waiting for \"pong\"\nconst auto data = co_await socket;\nco_return calculateLatency(data);\n```\n\n📘 [Full documentation here](https://qcoro.dev/reference/core/qiodevice).\n\n### ...and more!\n\nGo check the [full documentation](https://qcoro.dev) to learn more.\n\n## .then() continuations\n\nSometimes it's not possible to use `co_await` to handle result of a coroutine - usually\nwhen interfacing with a 3rd party code that does not support coroutines. In those\nscenarios it's possible to chain a continuation callback to the coroutine which will\nget invoked asynchronously when the coroutine finishes.\n\n```cpp\nvoid regularFunction() {\n    someCoroutineReturningInt().then([](int result) {\n        // handle result\n    });\n}\n```\n\nThe continuation callback can also be a coroutine and the result of the entire\nexpression is Task\u003cT\u003e where T is the return type of the continuation. Thanks to\nthat it's possible to `co_await` the entire chain, or chain multiple `.then()`\ncontinuations.\n\n📘 [Full documentation here](https://qcoro.dev/reference/coro/task).\n\n## Generators\n\nGenerator is a coroutine that lazily produces multiple values. While there's\nnothing Qt-specific, QCoro provides the necessary tools for users to create\ncustom generators in their Qt applications.\n\nQCoro provides API for both synchronous generators (`QCoro::Generator\u003cT\u003e`)\nand asynchronous generators (`QCoro::AsyncGenerator\u003cT\u003e`). Both generators provide\ncontainer-like API: `begin()` and `end()` member functions that return iterator-like\nobjects, which is well-known and established API and makes generators compatible\nwith existing algorithms.\n\n```cpp\nQCoro::Generator\u003cint\u003e fibonacci() {\n    quint64 a = 0, b = 0;\n    Q_FOREVER {\n        co_yield b;\n        const auto tmp = b;\n        a = b;\n        b += tmp;\n    }\n}\n\nvoid printFib(quint64 max) {\n    for (auto fib : fibonacci()) {\n        if (fib \u003e max) {\n            break;\n        }\n        std::cout \u003c\u003c fib \u003c\u003c std::endl;\n    }\n}\n```\n\n📘 [Full documentation here](https://qcoro.dev/reference/coro/generator).\n\n## License\n\n```text\nMIT License\n\nCopyright (c) 2022 Daniel Vrátil \u003cdvratil@kde.org\u003e\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n","funding_links":["https://github.com/sponsors/danvratil","https://liberapay.com/dvratil","https://ko-fi.com/dvratil","https://paypal.me/dvratil"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqcoro%2Fqcoro","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqcoro%2Fqcoro","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqcoro%2Fqcoro/lists"}