PyQt Checkboxes Issue

Hi all.

Coming back to PyQt after some a while of not using it and I’m stuck trying to create something that I thought would be simple.

I have two check boxes a and b, I want it so that both can be off but both can never be on. So if a is on and you check b, it automatically turns a off.

I thought simple, when ever the state changes check to see if the other is on and if it is turn it off.

The problem comes when I turn it off using code it triggers the state changed signal, so it runs the check for the other checkbox.

Is there a way round this?

Cheers.

It might not be obvious but the easiest is to put x number of radiobuttons inside a groupbox :stuck_out_tongue: they automatically uncheck eachother :slight_smile:

Best regards Yaz!

Thanks that works almost perfectly, the only issue is it wont allow you to have neither selected, one always has to be selected.

Ah. Yeah just tested that.

You can subclass QCheckBox and add a method you call setUnchecked() that always makes it unchecked
Note: don’t forget to call super :slight_smile:

Then what I would do is subclass QGroupBox and call it something like QCheckBoxGroup…
Note: don’t forget to call super :slight_smile:

Then I would add a layout inside it and then make methods for:
AddCheckBox( takes a QCheckBox as a parameter)
GetCheckBox
RemoveCheckBox

I would use a layout to position the added checkboxes. The AddCheckBox method should also handle the SIGNAL connections. Since you have subclassed QCheckBox you can EVEN expose your own signals and have 100% control of what should happen and what not

Thats too much work for such a simple thing lol, I’m too lazy to do that tonight.

I might just have 3 boxes one that says all lol.

Cheers for reply, hopefully I’ll get round to trying it that way, although never subclassed any of the classes so it could be interesting.

Cheers.

5 mins actually :slight_smile:


from PyQt4 import QtCore, QtGui


#CHECKBOX EXTENDED
class QCheckBoxExtended(QtGui.QCheckBox):
    def __init__(self, parent=None):
        super(QCheckBoxExtended, self).__init__(parent)

    def setUnchecked(self, value):
        print value
        if value is True:
            self.setChecked(False)

        
#CHECKBOX GROUP
class QCheckBoxGroup(QtGui.QGroupBox):
    def __init__(self, parent=None):
        super(QCheckBoxGroup, self).__init__(parent)
        self.layout = QtGui.QVBoxLayout(self)
        self.checkBoxList = []
    
    def addCheckBox(self, checkBox):

        for cb in self.checkBoxList:
            checkBox.connect(cb, QtCore.SIGNAL("toggled(bool)"), checkBox.setUnchecked)
            cb.connect(checkBox, QtCore.SIGNAL("toggled(bool)"), cb.setUnchecked)
        
        self.checkBoxList.append(checkBox)
        self.layout.addWidget(checkBox)


if __name__ == '__main__':

    import sys

    app = QtGui.QApplication(sys.argv)
    widget = QCheckBoxGroup()
    widget.addCheckBox(QCheckBoxExtended())
    widget.addCheckBox(QCheckBoxExtended())
    widget.addCheckBox(QCheckBoxExtended())    
    widget.show()
    sys.exit(app.exec_())

Show off lol.

Cheers for that, reading your code actually lead me to a much easier solution, well easier for me.

You used the toggled signal which is from the QAbstractButton class which lead me to look into what other signals it has and there is one called Clicked, which is only sent when the user actually clicks the checkbox and is not affected by setChecked method.

Thanks again for your help, I’ve saved your code for reading later so I can learn from it.

Cheers.

Not showoff :smiley: I just needed something to post on my blog xD

Cool cool :slight_smile:

The easiness of a solution might be less modular though :stuck_out_tongue_winking_eye: and you’ll rewrite code if you need to use the same thing somewhere else.

The more complex way I did allows you to import it and reuse several times. Including inside PyQT Designer (for placement) by just promoting a QGroupBox to QCheckBoxGroup (right click, promote) :slight_smile:

Anyhow whatever works for you :smiley:

Didn’t know it could be used inside the designer definitely check that out tomorrow.

Cheers again, really appreciate the help.

hihi don’t mention it :slight_smile:

Helping is fun!