<div dir="ltr"><div>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.<br>


</div><div><br></div><div><div>From the docs I thought it could be explicitly done at the connection side with the use of:<br></div></div><div><br></div><div><font face="courier new, monospace">    button.clicked[].connect(foo)</font></div>


<div><br></div><div>or it could be explicit at the slot instead (?) that we want the parameter-free one via:</div><div><br></div><div><font face="courier new, monospace">    @pyqtSlot()</font></div><div><font face="courier new, monospace">    def foo():</font></div>


<div><br></div><div>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.</div><div><br></div><div>How do I force PyQt5 to *not* connect up the version with the (bool, ) signature?</div>


<div><br></div><div>Full example code is below, with a stripped down example of the decorator issue:<br></div><div><br></div><div><div><font face="courier new, monospace">import sys</font></div><div><font face="courier new, monospace">from PyQt5 import QtWidgets</font></div>

<div><font face="courier new, monospace">from PyQt5.QtCore import pyqtSlot</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">app = QtWidgets.QApplication(sys.argv)</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">w = QtWidgets.QWidget()</font></div>

<div><font face="courier new, monospace">w.setWindowTitle('Signal connection checking')</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">b1 = QtWidgets.QPushButton("Connection to ()")</font></div>


<div><font face="courier new, monospace">b2 = QtWidgets.QPushButton("Connection to (checked)")</font></div><div><font face="courier new, monospace">b3 = QtWidgets.QPushButton("Connection to (*args)")</font></div>

<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">layout = QtWidgets.QVBoxLayout(w)</font></div><div><font face="courier new, monospace">layout.addWidget(b1)</font></div>
<div><font face="courier new, monospace">layout.addWidget(b2)</font></div><div><font face="courier new, monospace">layout.addWidget(b3)</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">def bogus_decorator(f):</font></div>

<div><font face="courier new, monospace">    def wrapper(*args):</font></div><div><font face="courier new, monospace">        print "wrapper called with args = %r" % (args, )</font></div>
<div><font face="courier new, monospace">        return f() #<-- have to do this to make the code work</font></div><div><font face="courier new, monospace">        #should be the code below, but it fails since we call with</font></div>

<div><font face="courier new, monospace">        #an unexpected arg and get a corresponding TypeError.</font></div>
<div><font face="courier new, monospace">        #return f(*args) #<--- will fails since it passes an unexpected arg</font></div><div><font face="courier new, monospace">    return wrapper</font></div><div><font face="courier new, monospace"><br>

</font></div><div><font face="courier new, monospace">def onVoidClick():</font></div><div><font face="courier new, monospace">    print "normal (void) clicked!"</font></div><div>
<font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">def onBoolClick(checked):</font></div><div><font face="courier new, monospace">    print "normal (bool) clicked!"</font></div>

<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">@pyqtSlot() #<-- shouldn't this force the parameter-free overload?</font></div><div><font face="courier new, monospace">@bogus_decorator</font></div>


<div><font face="courier new, monospace">#@pyqtSlot()  #<--- order does not matter</font></div><div><font face="courier new, monospace">def onWrappedStarClick():</font></div><div><font face="courier new, monospace">    #this always gets called with the (bool) overload</font></div>

<div><font face="courier new, monospace">    print "Actual handler fired!"</font></div><div><font face="courier new, monospace"><br></font></div>
<div><font face="courier new, monospace">b1.clicked.connect(onVoidClick)</font></div><div><font face="courier new, monospace">b2.clicked.connect(onBoolClick)</font></div><div><font face="courier new, monospace"><br></font></div>

<div><font face="courier new, monospace">#How to connect this next one so that it works like onVoidClick()?</font></div><div><font face="courier new, monospace"># - explicitly defining the slot with @pyqtSlot() does not work</font></div>


<div><font face="courier new, monospace"># - explicitly connecting an overload with clicked[()].connect doesn't work</font></div><div><font face="courier new, monospace">b3.clicked.connect(onWrappedStarClick)</font></div>

<div><font face="courier new, monospace">#b3.clicked[()].connect(onStarClick)</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">w.show()</font></div><div>
<font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">sys.exit(app.exec_())</font></div><div><br></div></div>
</div>