[PyQt] Signals and class inheritance

Will Hall june.2016 at gnatter.net
Thu Sep 29 07:36:06 BST 2016


Hi all,

I've noticed an inconsistency with signal inheritance between PyQt4 and
PySide. The following simple example attempts to redefine stateChanged
on a QComboBox in a derived class. I've condensed the problem into the
following example:

from qtpy import QtCore, QtGui, QtWidgets

class CheckBox(QtWidgets.QCheckBox):

	stateChanged = QtCore.Signal(int)
	def __init__(self, parent=None):
		super(CheckBox, self).__init__(parent)

def findSignals(widget):
	metaObject = widget.metaObject()
	for idx in xrange(metaObject.methodCount()):
		if metaObject.method(idx).methodType() == QtCore.QMetaMethod.Signal:
			yield metaObject.method(idx).signature()

def called(state):
	print 'state changed', state

def main():
	app = QtGui.QApplication(sys.argv)

	checkBox = CheckBox()
	checkBox.stateChanged.connect(called)
	print ('SIGNALS=', list(findSignals(checkBox)))

	checkBox.setCheckState(QtCore.Qt.Checked)

I'm using QtPy abstraction library to comapre Pyt4 against PySide, but
the same behaviour is seen when using direct PyQt4/PySide imports.

$ QT_API=pyside python2 test.py
('SIGNALS=', ['destroyed(QObject*)', 'destroyed()',
'customContextMenuRequested(QPoint)', 'pressed()', 'released()',
'clicked(bool)', 'clicked()', 'toggled(bool)', 'stateChanged(int)'])
state changed 2

$ QT_API=pyqt python2 test.py
('SIGNALS=', ['destroyed(QObject*)', 'destroyed()',
'customContextMenuRequested(QPoint)', 'pressed()', 'released()',
'clicked(bool)', 'clicked()', 'toggled(bool)', 'stateChanged(int)',
'stateChanged(int)'])

Notice that in PyQt4 the stateChanged(int) signal is defined twice but
does not trigger my callback function "called()".

Any insight into this would be gratefully received!

Regards,
Will



More information about the PyQt mailing list