0

I am looking for a way to control a (child) QCheckBox with a (parent) QCheckBox.

At the beginning, the child checkbox should be disabled until the parent chbox is checked.

Once the parent chbox is checked, the user should be able to interact with the child chbox. However, if the parent chbox is unchecked, the child chbox should be reset to the uncheck state.

Here is the code I have so far

import os
import sys
from functools import partial
from PySide.QtCore import *
from PySide.QtGui import *

class TestDialog(QDialog):

    def __init__(self):
        super(TestDialog,self).__init__()

        self.setWindowTitle('Checkbox Family')
        self.initUI()
        self.show()

    def initUI(self):
        # Checkboxes
        parentChbox = QtGui.QCheckBox('Parent', self)
        parentChbox.resize(parentChbox.sizeHint())

        sonChbox = QtGui.QCheckBox('Son', self)
        sonChbox.resize(sonChbox.sizeHint())
        sonChbox.setEnabled(False)
        sonChbox.setCheckState(Qt.Unchecked)

        daughterChbox = QtGui.QCheckBox('Daughter', self)
        daughterChbox.resize(daughterChbox.sizeHint())
        daughterChbox.setEnabled(False)
        daughterChbox.setCheckState(Qt.Unchecked)

        # Layout
        chboxLayout = QtGui.QHBoxLayout()
        chboxLayout.addWidget(parentChbox)
        chboxLayout.addWidget(sonChbox)
        chboxLayout.addWidget(daughterChbox)

        self.setLayout(chboxLayout)

        # Event handling 
        parentChbox.stateChanged.connect(partial(self.parent_check, sonChbox))


    def parent_check(self, childChbox):
        if self.sender().isChecked():
            childChbox.setEnabled(True)
        else:
            # [HELP] If the child checkbox becomes disabled, reset it to uncheck
            if childChbox.isEnabled(False):
                childChbox.setCheckState(Qt.Unchecked)
            else:
                pass

dia = TestDialog()

I've searching for days and found out about the functools.partial and also the lambda to pass the child checkbox as an extra argument into the slot method. I have this error when I start checking the parentChbox

TypeError: parent_check() takes exactly 2 arguments (3 given)

Has anyone ever get through this point, could you please give me some direction to move on?

Thank you so much.

tung
  • 1
  • 1

2 Answers2

0

In order to interact with the check-boxes, they should be created as instance variables of the class TestDialog, like this:

 def initUI(self):
        self.parentChbox =QtGui.QCheckBox('Parent', self)
        self.sonChbox =QtGui.QCheckBox('Son', self)
        self.sonChbox.setEnabled(False)
        self.sonChbox.setCheckState(QtCore.Qt.Unchecked)

Then you don't need partial or lambda. You can connect self.parentChbox.stateChanged directly to the function parent_check.

The stateChanged signal of a check-box comes with a state parameter, so you can do something like this:

def parent_check(self,state):
    if state==QtCore.Qt.Checked:
        self.sonChbox.setEnabled(True)
    else:
        self.sonChbox.setEnabled(False)
        self.sonChbox.setCheckState(QtCore.Qt.Unchecked)

Thanks to self, in any method of Testdialog you can easilly access your check-boxes.

Mel
  • 5,837
  • 10
  • 37
  • 42
0

Replace parentChbox.stateChanged.connect(partial(self.parent_check, sonChbox)) with parentChbox.toggled.connect(lambda state: self.setState(state, sonChbox))

And then add the following method to your class

def setState(self, state, son):
    son.setEnabled(state)
    if not state:
        son.setChecked(state)
qurban
  • 3,885
  • 24
  • 36
  • While not an immediate problem, there is a risk that your code breaks if `sonChbox` is modified to point to a different checkbox after the connection is made (for example if this code was used inside a loop). This is because the expression inside the `lambda` is evaluated when the lambda is called, not when it is defined. See [here](http://stackoverflow.com/a/19523242/1994235) for full details, but the solution is to define the lambda as `lambda state, sonChbox=sonChbox: self.setState(state, sonChbox)` – three_pineapples Jun 25 '15 at 11:35