QT - Как разместить виджеты во взаимоисключающих группах?

Я хочу сделать что-то вроде следующего:

пример

Но с переключателями вместо флажков. На изображении выше виджеты размещены в группы, которые можно включить / отключить, но я хочу, чтобы за один раз была включена только одна группа (в примере включены и группа A, и группа C).

Я сделал вышеупомянутый пример, используя QGroupBox, но он предоставляет только обычные флажки, а не переключатели, насколько я могу судить.

1 ответ

Решение

Ckeckbox, который появляется в QGroupBox это не QCheckBoxЭто всего лишь рисунок. Таким образом, возможное решение заключается в создании класса, который управляет QGroupBox проверено.

#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();
}

Вы можете связать каждый сигнал QGroupBox'toggled с другим слотом setDisabled.

ps: Я знаю, что уже слишком поздно, но я просто кладу его сюда, если это кому-то еще нужно.

Другие вопросы по тегам