0

When I enable a child of my QGroupBox after unchecking the group box, that child is enabled. But if I do the same to a grandchild widget, that widget remains disabled. I would expect all children of an unchecked group box to act the same as all children of a disabled parent widget (with respect to being enabled).

Enabled child in an unchecked group box

Gist of the code used to create the image above.

What should I do to ensure my child automatically remains disabled, even if I call child.setEnabled(true) after the group box is unchecked?

I am using Qt 5.9.1.

jtooker
  • 1,043
  • 1
  • 8
  • 22

2 Answers2

0

This appears to be a known bug.

At the moment, you need to know if the parent group box is checked to call setEnabled on a child widget:

child.setEnabled(groupBox.isChecked() && otherCondition);
jtooker
  • 1,043
  • 1
  • 8
  • 22
0

That happens because a QGroupBox itself is not disabled when the checkbox is off, and thus normal widget enablement propagation doesn't apply to this behavior. This workaround is IMHO sensible. The only possible workaround via public APIs would be to add a viewport child widget in the groupbox, and make the everything a child of that viewport:

class GroupBoxViewport : public QWidget {
  Q_OBJECT
  void updateGeometry() {
    if (parent())
      setGeometry(parentWidget()->contentsRect());
  }
  void newParent() {
    if (parent()) {
      parent()->installEventFilter(this);
      updateGeometry();
    }
  }
protected:
  bool eventFilter(QObject *obj, QEvent *ev) override {
    if (obj == parent() && ev->type() == QEvent::Resize)
      updateGeometry();
    return QWidget::eventFilter(obj, ev);
  }
  bool event(QEvent *ev) override {
    if (ev->type() == QEvent::ParentAboutToChange) {
      if (parent())
        parent()->uninstallEventFilter(this);
    } else if (ev->type() == QEvent::ParentChange)
      newParent();
    return QWidget::event(ev);
  }
public:
  QWidget(QWidget *parent = {}) : QWidget(parent) {
    newParent();
  }
};

Then, set the layout on and add all the children to the viewport:

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);
  QGroupBox box("The Group");
  GroupBoxViewPort viewport(&box);
  QVBoxLayout layout(&viewport);
  QLabel label("A, uh, member of the group");
  layout.addwidget(&label);
  box.show();
  return app.exec();
}
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313