Closed
Description
It seems that run_forever
has the effect of calling QApplication.exec()
while simultaneously running the event loop tasks. When exec
returns, the event loop stops and run_forever
returns. At this point I would like to send a stop signal to the other tasks to perform cleanup actions, and then restart the loop and run it until the tasks are complete. I came up with a solution, pasted below. This issue is a suggestion to elaborate the docstring / add an example, and to help others.
Thanks for your work.
import sys
from PyQt5 import QtWidgets
import qasync
import asyncio
class Widget(QtWidgets.QWidget):
"""A widget with a single label."""
def __init__(self):
QtWidgets.QWidget.__init__(self)
self._label = QtWidgets.QLabel()
b0 = QtWidgets.QHBoxLayout()
self.setLayout(b0)
b0.addWidget(self._label)
def set_text(self, text):
"""Set the text of the label."""
self._label.setText(text)
stop_flag = False
async def start_counting(widget):
try:
n = 0
while not stop_flag:
widget.set_text(str(n))
await asyncio.sleep(1)
n += 1
print('Counting stopped.')
except BaseException as e:
print('Counting cancelled.')
app = QtWidgets.QApplication(sys.argv)
widget = Widget()
widget.show()
loop = qasync.QEventLoop(app)
task = loop.create_task(start_counting(widget))
# Runs until last widget closed, like QApplication.exec().
loop.run_forever()
assert not loop.is_running()
# Looking at the __init__.py in qasync, it seems that it stopped running because QApplication.exec() returned.
# However, our counting task is incomplete.
tasks = asyncio.all_tasks()
assert len(tasks) == 1
# Send stop signal. Alternative, can cancel.
stop_flag = True
# task.cancel()
# Restart the loop to finish the tasks. In this example there is only one, but gather them for generality.
gathered = asyncio.gather(*tasks)
loop.run_until_complete(gathered)
# The following does not work.
# loop.run_forever()
print('All done.')
Metadata
Metadata
Assignees
Labels
No labels