Thalia
Thalia

Reputation: 14615

Alternately checking checkable QGroupboxes

I am trying to add checked gropuboxes, and if one groupbox is checked the other should be unchecked.

So I thought, I add

    connect(m_grp1, SIGNAL(toggled(bool)), this, SLOT(grp1Changed(bool)));
    connect(m_grp2, SIGNAL(toggled(bool)), this, SLOT(grp2Changed(bool)));

But if I change the check on grp2 when grp1 changes, that will trigger a change in grp2, which will trigger a change in grp1...

Is there anything built-in that I can use - like radio buttons ? Or I can't use the checked group boxes and must implement the behavior with radio buttons myself ?

My code (Qt 4.8):
Should add in a grid layout 2 checked group boxes, each with some items inside in a grid layout, both boxes checkable and one of them checked.

groupboxes.h

#ifndef GROUPBOXES_H
#define GROUPBOXES_H

#include <QtGui>

class GroupBoxes : public QWidget
{
    Q_OBJECT

public:
    GroupBoxes(QWidget *parent = 0);

private slots:
    void grp1Changed(bool _on);
    void grp2Changed(bool _on);

private:
    QGroupBox *m_grp2;
    QGroupBox *m_grp1;

    void setGroup1();
    void setGroup2();
};

#endif // GROUPBOXES_H


groupboxes.cpp

#include "groupboxes.h"

GroupBoxes::GroupBoxes(QWidget *parent)
    : QWidget(parent)
{
    setGroup1();
    setGroup2();

    connect(m_grp1, SIGNAL(toggled(bool)), this, SLOT(grp1Changed(bool)));
    connect(m_grp2, SIGNAL(toggled(bool)), this, SLOT(grp2Changed(bool)));
    QGridLayout *grid = new QGridLayout;

    grid->addWidget(m_grp1, 0, 0);
    grid->addWidget(m_grp2, 1, 0);
    setLayout(grid);

    setWindowTitle(tr("Group Boxes"));
    resize(480, 320);
}

void GroupBoxes::setGroup1()
{
    QLabel lbl1 = new QLabel(tr("def"));
    m_grp1 = new QGroupBox("DEF");
    m_grp1->setCheckable(true);
    m_grp1->setChecked(true);
    QGridLayout *boxLayout1 = new QGridLayout;
    boxLayout1->addWidget(lbl1, 0, 0, 1, 1);
    m_grp1->setLayout(boxLayout1);
}

void GroupBoxes::setGroup2()
{
    QLabel lbl1 = new QLabel(tr("abc"));
    m_grp2 = new QGroupBox("ABC");
    m_grp2->setCheckable(true);
    m_grp2->setChecked(false);
    QGridLayout *boxLayout = new QGridLayout;
    boxLayout->addWidget(lbl1, 0, 0, 1, 1);   
    m_grp2->setLayout(boxLayout);
}

void GroupBoxes::grp1Changed(bool _on)
{
    m_grp2->setChecked(!_on);  // but that would trigger grp2Changed and will lead to infinite loop
}
void GroupBoxes::grp2Changed(bool _on)
{
    m_grp1->setChecked(!_on);  // but that would trigger grp1Changed and will lead to infinite loop
}


main.cpp

#include <QApplication>
#include "groupboxes.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    GroupBoxes window;
    window.show();
    return a.exec();
}

Upvotes: 0

Views: 1594

Answers (3)

B&#246;rkn
B&#246;rkn

Reputation: 38

You need to uncheck your checkbox and you need to use SignalBlocker for not getting in an infinite loop

void GroupBoxes::grp1Changed(bool _on){
QSignalBlocker(m_grp2);
QSignalBlocker(m_grp1);
m_grp2->setChecked(!_on);
m_grp1->setChecked(_on);
}

but you should use RadioButtons in the same Layout since it's not possible to check more than 1 RadioButton.

Upvotes: 2

Hamish Moffatt
Hamish Moffatt

Reputation: 831

You can add the QCheckBox widgets to a QButtonGroup. The QButtonGroup takes care of making sure only one of its members is set. Or use the autoExclusive property.

Or use a QRadioButton if that's what you really intended. You should only use checkboxes for this purpose if you want to be able to deselect both.

Upvotes: 0

Thalia
Thalia

Reputation: 14615

I'll do

void GroupBoxes::grp1Changed(bool _on)
{
    if(_on)
        m_grp2->setChecked(false);  
}

That way I seem to avoid infinite loop because I only change on true, and set change to false.

Upvotes: 1

Related Questions