harvimt / quamash

Implementation of the PEP 3156 event-loop (asyncio) api using the Qt Event-Loop
BSD 2-Clause "Simplified" License
264 stars 46 forks source link

Add more support for qt signals in futures #93

Closed Wesmania closed 6 years ago

Wesmania commented 6 years ago

This set of commits adds support for awaiting on PyQt signals, as well as emitting a signal once a future / task is done. While it's a non-standard addition, I believe it's very useful for any code utilizing Qt - with that, interaction with regular signalling Qt code becomes much more convenient. Now we can await on dialogs or signals in user code, and a future can be connected with Qt style code with its 'done' signal.

Fixes #90.

Wesmania commented 6 years ago

I did not document any of the features yet - I'll do that tomorrow morning.

harvimt commented 6 years ago

documentation would be really helpful.

In particular, can you explain how this differs from, this

import functools
from asyncio import Future

# myobject  is an instance of QObject or a subclass of QObject & myobject.mysignal is a signal
future = asyncio.Future()
myobject.mysignal.connect(functools.partial(future.set_result))
await future
harvimt commented 6 years ago

(I'd also really prefer if the tests pass in CI before merging, but the tests are quite finicky especially the appveryor tests)

Wesmania commented 6 years ago

It doesn't actually differ much, beyond being able to await on multiple signals at a time (which can be done just by connecting to multiple signals), queueing results and keeping references to lambdas (since PyQt for example doesn't allow us to disconnect them). The example you've provided is probably a better solution than adding an extra method to the event loop. I don't know if 'done' signals for futures can be extracted that way as well.

I'll look at the tests.

harvimt commented 6 years ago

I mean... you can await multiple futures with asyncio.wait, but I guess it's kind of awkward.

Wesmania commented 6 years ago

Since awaiting of signals is implementable without touching the event loop, I can reduce the PR just to 'done' signals for futures, if you'd like. Of course with some manual wrapping and 'add_done_callback' this can be shoved outside as well.

Wesmania commented 6 years ago

So I got more familiar / comfortable with Python's asyncio and figured out this has no business being in the event loop, indeed. Sorry for taking your time, at least it was a learning experience for me :)