c++qtqt5qgroupbox

QT - How to place widgets in mutually exclusive groups?


I'm looking to do something like the following:

example

But with radio buttons instead of checkboxes. In the above picture widgets are placed into groups which can be enabled/disabled, but I want only 1 group to be enabled at a time (in the example both Group A and Group C are enabled).

I did the above example using QGroupBox, but it only provides normal checkboxes, not radio buttons as far as I can tell.


Solution

  • The ckeckbox that appears in the QGroupBox is not a QCheckBox, it is just a drawing. So a possible solution is to create a class that manages the QGroupBox checked.

    #include <QApplication>
    #include <QGroupBox>
    #include <QLineEdit>
    #include <QRadioButton>
    #include <QSlider>
    #include <QVBoxLayout>
    
    class ExclusiveManager: public QObject{
    public:
        using QObject::QObject;
        void addGroupBox(QGroupBox *groupbox){
            if(groupbox){
                groupbox->blockSignals(true);
                groupbox->setChecked(m_groupboxs.isEmpty());
                groupbox->blockSignals(false);
                m_groupboxs << groupbox;
                connect(groupbox, &QGroupBox::toggled, this, &ExclusiveManager::onToggled);
            }
        }
    private slots:
        void onToggled(bool on){
            QGroupBox *groupbox = qobject_cast<QGroupBox *>(sender());
            if(on){
                for(QGroupBox *g: m_groupboxs){
                    if(g != groupbox && g->isChecked()){
                        g->blockSignals(true);
                        g->setChecked(false);
                        g->blockSignals(false);
                    }
                }
            }
            else{
                groupbox->blockSignals(true);
                groupbox->setChecked(false);
                groupbox->blockSignals(false);
            }
        }
    private:
        QList<QGroupBox *> m_groupboxs;
    };
    
    class Widget: public QWidget{
    public:
        Widget(QWidget *parent=nullptr):QWidget(parent){
            setLayout(new QVBoxLayout);
    
            ExclusiveManager *manager = new ExclusiveManager(this);
    
            group_a = new QGroupBox("Group A");
            group_a->setCheckable(true);
            group_b = new QGroupBox("Group B");
            group_b->setCheckable(true);
            group_c = new QGroupBox("Group C");
            group_c->setCheckable(true);
            layout()->addWidget(group_a);
            layout()->addWidget(group_b);
            layout()->addWidget(group_c);
    
            manager->addGroupBox(group_a);
            manager->addGroupBox(group_b);
            manager->addGroupBox(group_c);
    
            QVBoxLayout *layA = new QVBoxLayout();
            layA->addWidget(new QLineEdit);
            group_a->setLayout(layA);
    
            QVBoxLayout *layB = new QVBoxLayout();
            layB->addWidget(new QRadioButton("Option 1"));
            layB->addWidget(new QRadioButton("Option 2"));
            group_b->setLayout(layB);
    
            QVBoxLayout *layC = new QVBoxLayout();
            layC->addWidget(new QSlider(Qt::Horizontal));
            group_c->setLayout(layC);
        }
    private:
        QGroupBox *group_a;
        QGroupBox *group_b;
        QGroupBox *group_c;
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget w;
        w.show();
    
        return a.exec();
    }