qtrio


Nameqtrio JSON
Version 0.7.0 PyPI version JSON
download
home_pagehttps://github.com/altendky/qtrio
Summarya library bringing Qt GUIs together with ``async`` and ``await`` via Trio
upload_time2023-06-07 15:49:17
maintainer
docs_urlNone
authorKyle Altendorf
requires_python>=3.7
licenseMIT -or- Apache License 2.0
keywords async io trio gui qt pyqt5 pyside2
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            QTrio - a library bringing Qt GUIs together with ``async`` and ``await`` via Trio
=================================================================================

Resources
---------

=================================  =================================  =============================

`Documentation <documentation_>`_  `Read the Docs <documentation_>`_  |documentation badge|
`Chat <chat_>`_                    `Gitter <chat_>`_                  |chat badge|
`Forum <forum_>`_                  `Discourse <forum_>`_              |forum badge|
`Issues <issues_>`_                `GitHub <issues_>`_                |issues badge|

`Repository <repository_>`_        `GitHub <repository_>`_            |repository badge|
`Tests <tests_>`_                  `GitHub Actions <tests_>`_         |tests badge|
`Coverage <coverage_>`_            `Codecov <coverage_>`_             |coverage badge|

`Distribution <distribution_>`_    `PyPI <distribution_>`_            | |version badge|
                                                                      | |python versions badge|
                                                                      | |python interpreters badge|

=================================  =================================  =============================


Introduction
------------

Note:
    This library is in early development.  It works.  It has tests.  It has
    documentation.  Expect breaking changes as we explore a clean API.  By paying this
    price you get the privilege to provide feedback via
    `GitHub issues <https://github.com/altendky/qtrio/issues>`__ to help shape our
    future.  ``:]``

The QTrio project's goal is to bring the friendly concurrency of Trio using Python's
``async`` and ``await`` syntax together with the GUI features of Qt to enable more
correct code and a more pleasant developer experience.  QTrio is `permissively licensed
<https://github.com/altendky/qtrio/blob/main/LICENSE>`__ to avoid introducing
restrictions beyond those of the underlying Python Qt library you choose.  Both PySide2
and PyQt5 are supported.

By enabling use of ``async`` and ``await`` it is possible in some cases to write
related code more concisely and clearly than you would get with the signal and slot
mechanisms of Qt concurrency.  In this set of small examples we will allow the user to
input their name then use that input to generate an output message.  The user will be
able to cancel the input to terminate the program early.  In the first example we will
do it in the form of a classic "hello" console program.  Well, classic plus a bit of
boilerplate to allow explicit testing without using special external tooling.  Then
second, the form of a general Qt program implementing this same activity.  And finally,
the QTrio way.

.. code-block:: python

    # A complete runnable source file with imports and helpers is available in
    # either the documentation readme examples or in the repository under
    # qtrio/examples/readme/console.py.

    def main(
        input_file: typing.TextIO = sys.stdin, output_file: typing.TextIO = sys.stdout
    ) -> None:
        try:
            output_file.write("What is your name? ")
            output_file.flush()
            name = input_file.readline()[:-1]
            output_file.write(f"Hi {name}, welcome to the team!\n")
        except KeyboardInterrupt:
            pass

Nice and concise, including the cancellation via ``ctrl+c``.  This is because we can
stay in one scope thus using both local variables and a ``try``/``except`` block.  This
kind of explodes when you shift into a classic Qt GUI setup.

.. code-block:: python

    # A complete runnable source file with imports and helpers is available in
    # either the documentation readme examples or in the repository under
    # qtrio/examples/readme/qt.py.

    class Main:
        def __init__(
            self,
            application: QtWidgets.QApplication,
            input_dialog: typing.Optional[QtWidgets.QInputDialog] = None,
            output_dialog: typing.Optional[QtWidgets.QMessageBox] = None,
        ):
            self.application = application

            if input_dialog is None:  # pragma: no cover
                input_dialog = create_input()

            if output_dialog is None:  # pragma: no cover
                output_dialog = create_output()

            self.input_dialog = input_dialog
            self.output_dialog = output_dialog

        def setup(self) -> None:
            self.input_dialog.accepted.connect(self.input_accepted)
            self.input_dialog.rejected.connect(self.input_rejected)

            self.input_dialog.show()

        def input_accepted(self) -> None:
            name = self.input_dialog.textValue()

            self.output_dialog.setText(f"Hi {name}, welcome to the team!")

            self.output_dialog.finished.connect(self.output_finished)
            self.output_dialog.show()

        def input_rejected(self) -> None:
            self.application.quit()

        def output_finished(self) -> None:
            self.application.quit()

The third example, below, shows how using ``async`` and ``await`` allows us to
return to the more concise and clear description of the sequenced activity.
Most of the code is just setup for testability with only the last four lines
really containing the activity.

.. code-block:: python

    # A complete runnable source file with imports and helpers is available in
    # either the documentation readme examples or in the repository under
    # qtrio/examples/readme/qtrio_example.py.

    async def main(
        *,
        task_status: trio_typing.TaskStatus[Dialogs] = trio.TASK_STATUS_IGNORED,
    ) -> None:
        dialogs = Dialogs()
        task_status.started(dialogs)

        with contextlib.suppress(qtrio.UserCancelledError):
            name = await dialogs.input.wait()
            dialogs.output.text = f"Hi {name}, welcome to the team!"
            await dialogs.output.wait()


.. _chat: https://gitter.im/python-trio/general
.. |chat badge| image:: https://img.shields.io/badge/chat-join%20now-blue.svg?color=royalblue&logo=Gitter&logoColor=whitesmoke
   :target: `chat`_
   :alt: Support chatroom

.. _forum: https://trio.discourse.group
.. |forum badge| image:: https://img.shields.io/badge/forum-join%20now-blue.svg?color=royalblue&logo=Discourse&logoColor=whitesmoke
   :target: `forum`_
   :alt: Support forum

.. _documentation: https://qtrio.readthedocs.io
.. |documentation badge| image:: https://img.shields.io/badge/docs-read%20now-blue.svg?color=royalblue&logo=Read-the-Docs&logoColor=whitesmoke
   :target: `documentation`_
   :alt: Documentation

.. _distribution: https://pypi.org/project/qtrio
.. |version badge| image:: https://img.shields.io/pypi/v/qtrio.svg?color=indianred&logo=PyPI&logoColor=whitesmoke
   :target: `distribution`_
   :alt: Latest distribution version

.. |python versions badge| image:: https://img.shields.io/pypi/pyversions/qtrio.svg?color=indianred&logo=PyPI&logoColor=whitesmoke
   :alt: Supported Python versions
   :target: `distribution`_

.. |python interpreters badge| image:: https://img.shields.io/pypi/implementation/qtrio.svg?color=indianred&logo=PyPI&logoColor=whitesmoke
   :alt: Supported Python interpreters
   :target: `distribution`_

.. _issues: https://github.com/altendky/qtrio/issues
.. |issues badge| image:: https://img.shields.io/github/issues/altendky/qtrio?color=royalblue&logo=GitHub&logoColor=whitesmoke
   :target: `issues`_
   :alt: Issues

.. _repository: https://github.com/altendky/qtrio
.. |repository badge| image:: https://img.shields.io/github/last-commit/altendky/qtrio.svg?color=seagreen&logo=GitHub&logoColor=whitesmoke
   :target: `repository`_
   :alt: Repository

.. _tests: https://github.com/altendky/qtrio/actions?query=branch%3Amaster
.. |tests badge| image:: https://img.shields.io/github/workflow/status/altendky/qtrio/CI/main?color=seagreen&logo=GitHub-Actions&logoColor=whitesmoke
   :target: `tests`_
   :alt: Tests

.. _coverage: https://codecov.io/gh/altendky/qtrio
.. |coverage badge| image:: https://img.shields.io/codecov/c/github/altendky/qtrio/main?color=seagreen&logo=Codecov&logoColor=whitesmoke
   :target: `coverage`_
   :alt: Test coverage

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/altendky/qtrio",
    "name": "qtrio",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "",
    "keywords": "async,io,Trio,GUI,Qt,PyQt5,PySide2",
    "author": "Kyle Altendorf",
    "author_email": "sda@fstab.net",
    "download_url": "https://files.pythonhosted.org/packages/c8/82/2298bfc9a9c03c3434cbd3800c0dc565d6062740bb864b73a649a71a38fc/qtrio-0.7.0.tar.gz",
    "platform": null,
    "description": "QTrio - a library bringing Qt GUIs together with ``async`` and ``await`` via Trio\n=================================================================================\n\nResources\n---------\n\n=================================  =================================  =============================\n\n`Documentation <documentation_>`_  `Read the Docs <documentation_>`_  |documentation badge|\n`Chat <chat_>`_                    `Gitter <chat_>`_                  |chat badge|\n`Forum <forum_>`_                  `Discourse <forum_>`_              |forum badge|\n`Issues <issues_>`_                `GitHub <issues_>`_                |issues badge|\n\n`Repository <repository_>`_        `GitHub <repository_>`_            |repository badge|\n`Tests <tests_>`_                  `GitHub Actions <tests_>`_         |tests badge|\n`Coverage <coverage_>`_            `Codecov <coverage_>`_             |coverage badge|\n\n`Distribution <distribution_>`_    `PyPI <distribution_>`_            | |version badge|\n                                                                      | |python versions badge|\n                                                                      | |python interpreters badge|\n\n=================================  =================================  =============================\n\n\nIntroduction\n------------\n\nNote:\n    This library is in early development.  It works.  It has tests.  It has\n    documentation.  Expect breaking changes as we explore a clean API.  By paying this\n    price you get the privilege to provide feedback via\n    `GitHub issues <https://github.com/altendky/qtrio/issues>`__ to help shape our\n    future.  ``:]``\n\nThe QTrio project's goal is to bring the friendly concurrency of Trio using Python's\n``async`` and ``await`` syntax together with the GUI features of Qt to enable more\ncorrect code and a more pleasant developer experience.  QTrio is `permissively licensed\n<https://github.com/altendky/qtrio/blob/main/LICENSE>`__ to avoid introducing\nrestrictions beyond those of the underlying Python Qt library you choose.  Both PySide2\nand PyQt5 are supported.\n\nBy enabling use of ``async`` and ``await`` it is possible in some cases to write\nrelated code more concisely and clearly than you would get with the signal and slot\nmechanisms of Qt concurrency.  In this set of small examples we will allow the user to\ninput their name then use that input to generate an output message.  The user will be\nable to cancel the input to terminate the program early.  In the first example we will\ndo it in the form of a classic \"hello\" console program.  Well, classic plus a bit of\nboilerplate to allow explicit testing without using special external tooling.  Then\nsecond, the form of a general Qt program implementing this same activity.  And finally,\nthe QTrio way.\n\n.. code-block:: python\n\n    # A complete runnable source file with imports and helpers is available in\n    # either the documentation readme examples or in the repository under\n    # qtrio/examples/readme/console.py.\n\n    def main(\n        input_file: typing.TextIO = sys.stdin, output_file: typing.TextIO = sys.stdout\n    ) -> None:\n        try:\n            output_file.write(\"What is your name? \")\n            output_file.flush()\n            name = input_file.readline()[:-1]\n            output_file.write(f\"Hi {name}, welcome to the team!\\n\")\n        except KeyboardInterrupt:\n            pass\n\nNice and concise, including the cancellation via ``ctrl+c``.  This is because we can\nstay in one scope thus using both local variables and a ``try``/``except`` block.  This\nkind of explodes when you shift into a classic Qt GUI setup.\n\n.. code-block:: python\n\n    # A complete runnable source file with imports and helpers is available in\n    # either the documentation readme examples or in the repository under\n    # qtrio/examples/readme/qt.py.\n\n    class Main:\n        def __init__(\n            self,\n            application: QtWidgets.QApplication,\n            input_dialog: typing.Optional[QtWidgets.QInputDialog] = None,\n            output_dialog: typing.Optional[QtWidgets.QMessageBox] = None,\n        ):\n            self.application = application\n\n            if input_dialog is None:  # pragma: no cover\n                input_dialog = create_input()\n\n            if output_dialog is None:  # pragma: no cover\n                output_dialog = create_output()\n\n            self.input_dialog = input_dialog\n            self.output_dialog = output_dialog\n\n        def setup(self) -> None:\n            self.input_dialog.accepted.connect(self.input_accepted)\n            self.input_dialog.rejected.connect(self.input_rejected)\n\n            self.input_dialog.show()\n\n        def input_accepted(self) -> None:\n            name = self.input_dialog.textValue()\n\n            self.output_dialog.setText(f\"Hi {name}, welcome to the team!\")\n\n            self.output_dialog.finished.connect(self.output_finished)\n            self.output_dialog.show()\n\n        def input_rejected(self) -> None:\n            self.application.quit()\n\n        def output_finished(self) -> None:\n            self.application.quit()\n\nThe third example, below, shows how using ``async`` and ``await`` allows us to\nreturn to the more concise and clear description of the sequenced activity.\nMost of the code is just setup for testability with only the last four lines\nreally containing the activity.\n\n.. code-block:: python\n\n    # A complete runnable source file with imports and helpers is available in\n    # either the documentation readme examples or in the repository under\n    # qtrio/examples/readme/qtrio_example.py.\n\n    async def main(\n        *,\n        task_status: trio_typing.TaskStatus[Dialogs] = trio.TASK_STATUS_IGNORED,\n    ) -> None:\n        dialogs = Dialogs()\n        task_status.started(dialogs)\n\n        with contextlib.suppress(qtrio.UserCancelledError):\n            name = await dialogs.input.wait()\n            dialogs.output.text = f\"Hi {name}, welcome to the team!\"\n            await dialogs.output.wait()\n\n\n.. _chat: https://gitter.im/python-trio/general\n.. |chat badge| image:: https://img.shields.io/badge/chat-join%20now-blue.svg?color=royalblue&logo=Gitter&logoColor=whitesmoke\n   :target: `chat`_\n   :alt: Support chatroom\n\n.. _forum: https://trio.discourse.group\n.. |forum badge| image:: https://img.shields.io/badge/forum-join%20now-blue.svg?color=royalblue&logo=Discourse&logoColor=whitesmoke\n   :target: `forum`_\n   :alt: Support forum\n\n.. _documentation: https://qtrio.readthedocs.io\n.. |documentation badge| image:: https://img.shields.io/badge/docs-read%20now-blue.svg?color=royalblue&logo=Read-the-Docs&logoColor=whitesmoke\n   :target: `documentation`_\n   :alt: Documentation\n\n.. _distribution: https://pypi.org/project/qtrio\n.. |version badge| image:: https://img.shields.io/pypi/v/qtrio.svg?color=indianred&logo=PyPI&logoColor=whitesmoke\n   :target: `distribution`_\n   :alt: Latest distribution version\n\n.. |python versions badge| image:: https://img.shields.io/pypi/pyversions/qtrio.svg?color=indianred&logo=PyPI&logoColor=whitesmoke\n   :alt: Supported Python versions\n   :target: `distribution`_\n\n.. |python interpreters badge| image:: https://img.shields.io/pypi/implementation/qtrio.svg?color=indianred&logo=PyPI&logoColor=whitesmoke\n   :alt: Supported Python interpreters\n   :target: `distribution`_\n\n.. _issues: https://github.com/altendky/qtrio/issues\n.. |issues badge| image:: https://img.shields.io/github/issues/altendky/qtrio?color=royalblue&logo=GitHub&logoColor=whitesmoke\n   :target: `issues`_\n   :alt: Issues\n\n.. _repository: https://github.com/altendky/qtrio\n.. |repository badge| image:: https://img.shields.io/github/last-commit/altendky/qtrio.svg?color=seagreen&logo=GitHub&logoColor=whitesmoke\n   :target: `repository`_\n   :alt: Repository\n\n.. _tests: https://github.com/altendky/qtrio/actions?query=branch%3Amaster\n.. |tests badge| image:: https://img.shields.io/github/workflow/status/altendky/qtrio/CI/main?color=seagreen&logo=GitHub-Actions&logoColor=whitesmoke\n   :target: `tests`_\n   :alt: Tests\n\n.. _coverage: https://codecov.io/gh/altendky/qtrio\n.. |coverage badge| image:: https://img.shields.io/codecov/c/github/altendky/qtrio/main?color=seagreen&logo=Codecov&logoColor=whitesmoke\n   :target: `coverage`_\n   :alt: Test coverage\n",
    "bugtrack_url": null,
    "license": "MIT -or- Apache License 2.0",
    "summary": "a library bringing Qt GUIs together with ``async`` and ``await`` via Trio",
    "version": "0.7.0",
    "project_urls": {
        "Chat": "https://gitter.im/python-trio/general",
        "Coverage": "https://codecov.io/gh/altendky/qtrio",
        "Distribution": "https://pypi.org/project/qtrio",
        "Documentation": "https://qtrio.readthedocs.io/",
        "Forum": "https://trio.discourse.group/",
        "Homepage": "https://github.com/altendky/qtrio",
        "Issues": "https://github.com/altendky/qtrio/issues",
        "Repository": "https://github.com/altendky/qtrio",
        "Tests": "https://github.com/altendky/qtrio/actions?query=branch%3Amain"
    },
    "split_keywords": [
        "async",
        "io",
        "trio",
        "gui",
        "qt",
        "pyqt5",
        "pyside2"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "61f4efd92132d1a4771fa3c159efc37384a6e9583b8ad84175154854086df894",
                "md5": "916faf046cec62896f3b66d22fd61676",
                "sha256": "58803879e29fa4260f34c1ce4f0e4521fd25083e5145072bdda4e3b1b5cb99a8"
            },
            "downloads": -1,
            "filename": "qtrio-0.7.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "916faf046cec62896f3b66d22fd61676",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 53349,
            "upload_time": "2023-06-07T15:49:15",
            "upload_time_iso_8601": "2023-06-07T15:49:15.904380Z",
            "url": "https://files.pythonhosted.org/packages/61/f4/efd92132d1a4771fa3c159efc37384a6e9583b8ad84175154854086df894/qtrio-0.7.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c8822298bfc9a9c03c3434cbd3800c0dc565d6062740bb864b73a649a71a38fc",
                "md5": "f7a28bbc91975a13da70738d82f8537e",
                "sha256": "98b3553598a057cbf053ed03f701f1be6e5b28647192b79e5a858763991cb974"
            },
            "downloads": -1,
            "filename": "qtrio-0.7.0.tar.gz",
            "has_sig": false,
            "md5_digest": "f7a28bbc91975a13da70738d82f8537e",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 60443,
            "upload_time": "2023-06-07T15:49:17",
            "upload_time_iso_8601": "2023-06-07T15:49:17.571686Z",
            "url": "https://files.pythonhosted.org/packages/c8/82/2298bfc9a9c03c3434cbd3800c0dc565d6062740bb864b73a649a71a38fc/qtrio-0.7.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-06-07 15:49:17",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "altendky",
    "github_project": "qtrio",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "lcname": "qtrio"
}
        
Elapsed time: 0.07323s