Package: qtrio
ResourcesDocumentationRead the DocsChatGitterForumDiscourseIssuesGitHubRepositoryGitHubTestsGitHub ActionsCoverageCodecovDistributionPyPIIntroductionNote: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 viaGitHub issuesto help shape our
future.:]The QTrio project’s goal is to bring the friendly concurrency of Trio using Python’sasyncandawaitsyntax together with the GUI features of Qt to enable more
correct code and a more pleasant developer experience.  QTrio ispermissively licensedto avoid introducing
restrictions beyond those of the underlying Python Qt library you choose.  Both PySide2
and PyQt5 are supported.By enabling use ofasyncandawaitit 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.# 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.defmain(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")exceptKeyboardInterrupt:passNice and concise, including the cancellation viactrl+c.  This is because we can
stay in one scope thus using both local variables and atry/exceptblock.  This
kind of explodes when you shift into a classic Qt GUI setup.# 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.classMain:def__init__(self,application:QtWidgets.QApplication,input_dialog:typing.Optional[QtWidgets.QInputDialog]=None,output_dialog:typing.Optional[QtWidgets.QMessageBox]=None,):self.application=applicationifinput_dialogisNone:# pragma: no coverinput_dialog=create_input()ifoutput_dialogisNone:# pragma: no coveroutput_dialog=create_output()self.input_dialog=input_dialogself.output_dialog=output_dialogdefsetup(self)->None:self.input_dialog.accepted.connect(self.input_accepted)self.input_dialog.rejected.connect(self.input_rejected)self.input_dialog.show()definput_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()definput_rejected(self)->None:self.application.quit()defoutput_finished(self)->None:self.application.quit()The third example, below, shows how usingasyncandawaitallows 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.# 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.asyncdefmain(*,task_status:trio_typing.TaskStatus[Dialogs]=trio.TASK_STATUS_IGNORED,)->None:dialogs=Dialogs()task_status.started(dialogs)withcontextlib.suppress(qtrio.UserCancelledError):name=awaitdialogs.input.wait()dialogs.output.text=f"Hi{name}, welcome to the team!"awaitdialogs.output.wait()