Question

def connect(signal):
    def result(func):
        signal.connect(func)
        return func
    return inner

def safemode(msg):
    def inner(func):
        @wraps(func):
        def result(*args, **kwargs):
            print 'Args passed to func:', args, kwargs
            try:
                func(*args, **kwargs)
            except:
                print msg
        return result
    return inner

@connect(form.my_action.triggered)
@safemode('Something bad'?)
def my_action():
    print 'Something good!'

So, when I trigger the action, I see:

Args passed to func: (False,) {}
Something bad?

Since my_action takes no arguments, calling func(*args, **kwargs) where func is my_action fails.

I know one solution is to just remove the *args, **kwargs but I'd like to use the same decorator for both Qt GUI functions and non-GUI functions.

The stack trace isn't very helpful; it just shows app.exec_() then the line where the failure occurs.

Where is that False coming from and how can I fix it?

Was it helpful?

Solution

There are a number of commonly-used signals with parameters that pass a default value. This includes QAction.triggered and QAbstractButton.clicked.

Effectively, these signals have two overloads as far PyQt is concerned: one that passes the default value, and one that doesn't. PyQt has a mechanism for explicitly choosing which one to use - but if it is not used, it will fall back to a hard-coded default. For the the above two signals, the default overload is the one that does pass a default value.

To select the overload which doesn't pass a value, do this:

form.my_action.triggered[()]

(NB: The getitem syntax of signal objects usually takes a type, or tuple of types, so an empty tuple is required to explicitly select an overload that has no parameters).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top