Nominate our 2022 Qt Champions!

Extending pyqtSlot

  • On one of my projects we use PyQt 5 and Python 3.4 with annotations for function call arguments (in a big application, this is really nice feature of Python). The builtin pyqtSlot decorator has two important limitations: it requires that slot parameter types be given eventhough they are already available via annotations; and there is no way to customize handling of (uncaught) exceptions raised in slots. So I extended pyqtSlot to fix both issues: our custom slot decorator introspects the annotations to automatically get the parameters to pass to pyqtSlot, and exceptions caught are routed to a customizable "error handler". It looks something like this:

    def ext_slot_handler(slot: callable, exc: BaseException, traceback_msg):
    print("BUG: slot {} raised exception {}:".format(slot, exc), file=sys.stderr)
    ...print other info like traceback etc...

    def ext_slot(func: callable) -> callable:
    arg_types = ... introspect func to get param types ...

    def wrapped_slot(*args):
          except BaseException as exc: 
               ext_slot_handler(slot, exc, traceback.format_exc())
    return pyqtSlot(*arg_types)(wrapped_slot)

    class Foo:
    def some_slot(self, arg1: int):
    print('hi', arg1)

    This even works with auto-connected slots thanks to wraps function of the functools module. If you forget to put annotation, ext_slot raises (this will happen at import time). If the arg to ext_slot is not a callable, it also raises at import time, this prevents mistakenly given parameters to ext_slot (for those who are so conditioned to giving params when using pyqtSlot).

    Any chance such functionality could be included in a future version of PyQt? I could post complete code if there is interest. Also, is there any capability of pyqtSlot that does not seem supported by ext_slot?

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    You should rather contact the River Bank Computing team since PyQt is their product

Log in to reply