[PyQt] How do you explicitly connect parameterless signals?

Russell Warren russ at perspexis.com
Sat May 24 00:08:43 BST 2014


I have some cases where I want to decorate my slots, where the decorator
has a typical (*args, **kwargs) catch-all signature.  Unfortunately, when
doing this, I'm unable to connect the signals and slots properly to a
parameter-free overload when one with parameters is available.

>From the docs I thought it could be explicitly done at the connection side
with the use of:

    button.clicked[].connect(foo)

or it could be explicit at the slot instead (?) that we want the
parameter-free one via:

    @pyqtSlot()
    def foo():

but I can't get either of these to work.  When my button slot has *args in
the params, I always get the 'checked' boolean.

How do I force PyQt5 to *not* connect up the version with the (bool, )
signature?

Full example code is below, with a stripped down example of the decorator
issue:

import sys
from PyQt5 import QtWidgets
from PyQt5.QtCore import pyqtSlot

app = QtWidgets.QApplication(sys.argv)

w = QtWidgets.QWidget()
w.setWindowTitle('Signal connection checking')

b1 = QtWidgets.QPushButton("Connection to ()")
b2 = QtWidgets.QPushButton("Connection to (checked)")
b3 = QtWidgets.QPushButton("Connection to (*args)")

layout = QtWidgets.QVBoxLayout(w)
layout.addWidget(b1)
layout.addWidget(b2)
layout.addWidget(b3)

def bogus_decorator(f):
    def wrapper(*args):
        print "wrapper called with args = %r" % (args, )
        return f() #<-- have to do this to make the code work
        #should be the code below, but it fails since we call with
        #an unexpected arg and get a corresponding TypeError.
        #return f(*args) #<--- will fails since it passes an unexpected arg
    return wrapper

def onVoidClick():
    print "normal (void) clicked!"

def onBoolClick(checked):
    print "normal (bool) clicked!"

@pyqtSlot() #<-- shouldn't this force the parameter-free overload?
@bogus_decorator
#@pyqtSlot()  #<--- order does not matter
def onWrappedStarClick():
    #this always gets called with the (bool) overload
    print "Actual handler fired!"

b1.clicked.connect(onVoidClick)
b2.clicked.connect(onBoolClick)

#How to connect this next one so that it works like onVoidClick()?
# - explicitly defining the slot with @pyqtSlot() does not work
# - explicitly connecting an overload with clicked[()].connect doesn't work
b3.clicked.connect(onWrappedStarClick)
#b3.clicked[()].connect(onStarClick)

w.show()

sys.exit(app.exec_())
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20140523/586ddf9e/attachment.html>


More information about the PyQt mailing list