thp / pyotherside

Python Bindings for Qt 5 and Qt 6. Allows you to access a CPython 3 interpreter directly from your Qt QML user interface code.
https://thp.io/2011/pyotherside/
Other
364 stars 49 forks source link

Add support for progress callback during calls to Python #60

Open estan opened 8 years ago

estan commented 8 years ago

When working with several concurrent calls to long-running Python functions it would be very convenient if the call API was something like:

call(var func, args=[], function callback(result) {}, function on_progress(progress) {})

Where the on_progress is a callable that, when provided, would would be made available as an on_progress kwarg on the Python side.

So for example, with a mymodule.py:

def do_stuff(arg1, arg2, on_progress=None):
    for i in range(3):
        sleep(1)        # Heavy work
        if on_progress is not None:
            on_progress(i)  # Report progress
    return 'Done!'

and the call from QML:

py.call('mymodule.dostuff', ['arg1', 'arg2'],
    function (result) {
        console.log('Result: ' + result);
    },
    function (progress) {
        console.log('Progress: ' + progress);
    }
);

which should output:

Progress: 0
Progress: 1
Progress: 2
Result: Done!

I know this functionality can be built on top of the existing send mechanism, but having it built in like this would save me from a lot of bookkeeping on the QML side to associate sent progress with the corresponding outstanding call.

Thanks a lot for pyotherside BTW. It looks very promising, and I'm fairly certain that we'll use it for the UI on our product, which is a machine for mineral analysis to be used in the mining industry.

thp commented 8 years ago

Yeah, we can probably do this by making it possible to wrap JS callables as arguments to Python (and vice versa might also make sense), so that we don't need to change the signature of call() and one could even pass multiple callables as argument for different situations.

Probably not going to have time to implement this in the near future, but feel free to send a pull request or send an e-mail if you actually need this for your commercial project.

estan commented 8 years ago

I actually began making a patch, but got distracted with some other things. I'll let you know if I dig into it again. At least the wish is here now :) And yea, to make it generally possible to pass callables as args like you say makes much more sense.

estan commented 8 years ago

Haven't had time to do anything on this yet, but just a question: The docs describe how you can pass QObjects to the Python side and call methods on them from there:

http://pyotherside.readthedocs.org/en/latest/#accessing-qobjects-from-python

Could I perhaps use this mechanism as a "progress callback" for now? I mean, pass in a QObject (QtObject {...} in QML) and call a progress(int) method on it to report back progress to the QML side?

thp commented 8 years ago

Yes, that should work.