Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connecting an overloaded PyQT signal using new-style syntax

I am designing a custom widget which is basically a QGroupBox holding a configurable number of QCheckBox buttons, where each one of them should control a particular bit in a bitmask represented by a QBitArray. In order to do that, I added the QCheckBox instances to a QButtonGroup, with each button given an integer ID:

    def populate(self, num_bits, parent = None):
        """
        Adds check boxes to the GroupBox according to the bitmask size
        """
        self.bitArray.resize(num_bits)
        layout = QHBoxLayout()

        for i in range(num_bits):
            cb = QCheckBox()
            cb.setText(QString.number(i))
            self.buttonGroup.addButton(cb, i)
            layout.addWidget(cb)
        self.setLayout(layout)

Then, each time a user would click on a checkbox contained in self.buttonGroup, I'd like self.bitArray to be notified so the corresponding bit in the array can be set/unset accordingly. For that I intended to connect QButtonGroup's buttonClicked(int) signal to QBitArray's toggleBit(int) method and, to be as pythonic as possible, I wanted to use new-style signals syntax, so I tried this:

self.buttonGroup.buttonClicked.connect(self.bitArray.toggleBit)

The problem is that buttonClicked is an overloaded signal, so there is also the buttonClicked(QAbstractButton*) signature. In fact, when the program is executing I get this error when I click a check box:

The debugged program raised the exception unhandled TypeError
"QBitArray.toggleBit(int): argument 1 has unexpected type 'QCheckBox'"

which clearly shows the toggleBit method received the buttonClicked(QAbstractButton*) signal instead of the buttonClicked(int) one.

So, the question is, how can I specify the signal connection, using new-style syntax, so that self.bitArray receives the buttonClicked(int) signal instead of the default overload - buttonClicked(QAbstractButton*)?

EDIT: The PyQT's New-style Signal and Slot Support documentation states you can use pyqtSlot decorators to specify which signal you want to connect to a given slot, but that is for a slot you are creating. What to do when the slot is from a "ready made" class? Is the only option subclassing it and then reimplementing the given slot with the right decorator?

like image 720
Claudio Avatar asked Jun 23 '12 21:06

Claudio


1 Answers

While browsing for related questions I found this answer to be exactly what I needed. The correct new-style signal syntax for connecting only QButtonGroup's buttonClicked(int) signal to QBitArray's toggleBit(int), ignoring the other overloaded signatures, involves specifying the desired type in brackets, like this:

self.buttonGroup.buttonClicked[int].connect(self.bitArray.toggleBit)
like image 91
Claudio Avatar answered Nov 15 '22 22:11

Claudio