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

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.