Qt中QToolBox切换页面时按钮setChecked(false)不生效问题求助
Qt QToolBox切换页面时无法取消上一页互斥按钮选中状态的解决方法
问题根源
核心问题是互斥模式的QButtonGroup不允许所有按钮处于未选中状态:当QButtonGroup::setExclusive(true)时,按钮组会强制保证至少有一个按钮被选中。所以你直接调用setChecked(false)时,按钮组会立刻把之前选中的按钮重新设为选中,导致isChecked()返回true。
另外,你写的onTriggered_btnGroup_1和onTriggered_btnGroup_2槽函数完全多余——互斥模式的按钮组本身就会自动处理点击选中逻辑,点击某个按钮时,组内其他按钮会自动取消选中,不需要手动遍历设置。
解决方案
1. 移除多余的槽函数及连接
删掉以下代码:
connect(btnGroup_1, &QButtonGroup::buttonClicked, this, &Widget::onTriggered_btnGroup_1);connect(btnGroup_2, &QButtonGroup::buttonClicked, this, &Widget::onTriggered_btnGroup_2);- 两个
onTriggered_btnGroup_*槽函数的实现
2. 修改页面切换逻辑,临时关闭互斥模式
要让互斥组的所有按钮都取消选中,需要先关闭互斥模式,设置完成后再重新开启:
connect(toolBox, &QToolBox::currentChanged, this, [=](int value) { preToolBoxIndex = curToolBoxIndex; curToolBoxIndex = value; QButtonGroup* prevGroup = ls[preToolBoxIndex]; // 临时关闭互斥,允许所有按钮未选中 prevGroup->setExclusive(false); for (auto btn : prevGroup->buttons()) { btn->setChecked(false); qInfo() << btn->isChecked(); // 此时会正确输出false } // 恢复互斥模式 prevGroup->setExclusive(true); });
3. 可选优化:确保初始索引一致
在createToolBox函数的最后,添加一行代码同步初始索引:
curToolBoxIndex = toolBox->currentIndex();
修改后的完整代码
#include <QApplication> #include <QWidget> #include <QToolBox> #include <QToolButton> #include <QGridLayout> #include <QLabel> #include <QButtonGroup> #include <QDebug> class Widget:public QWidget { public: Widget(QWidget* parent = nullptr):QWidget(parent) { this->resize(300, 300); createToolBox(); } ~Widget() {} void createToolBox() { // 第一页按钮组 ls.push_back(btnGroup_1 = new QButtonGroup); btnGroup_1->setExclusive(true); QGridLayout* gird_1 = new QGridLayout; gird_1->addWidget(createToolButton("toolButton_a1",1), 0, 0); gird_1->addWidget(createToolButton("toolButton_a2",1), 1, 0); QWidget* widget_1 = new QWidget; widget_1->setLayout(gird_1); // 第二页按钮组 ls.push_back(btnGroup_2 = new QButtonGroup); btnGroup_2->setExclusive(true); QGridLayout* gird_2 = new QGridLayout; gird_2->addWidget(createToolButton("toolButton_b1",2), 0, 0); gird_2->addWidget(createToolButton("toolButton_b2",2), 1, 0); QWidget* widget_2 = new QWidget; widget_2->setLayout(gird_2); // 创建QToolBox toolBox = new QToolBox(this); toolBox->setMinimumWidth(200); toolBox->setMaximumWidth(200); toolBox->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); toolBox->addItem(widget_1, "widget_1"); toolBox->addItem(widget_2, "widget_2"); // 页面切换处理 connect(toolBox, &QToolBox::currentChanged, this, [=](int value) { preToolBoxIndex = curToolBoxIndex; curToolBoxIndex = value; QButtonGroup* prevGroup = ls[preToolBoxIndex]; prevGroup->setExclusive(false); for (auto btn : prevGroup->buttons()) { btn->setChecked(false); qDebug() << btn->isChecked(); } prevGroup->setExclusive(true); }); // 同步初始索引 curToolBoxIndex = toolBox->currentIndex(); } QWidget* createToolButton(const QString& text,int type) { QToolButton* btn = new QToolButton; btn->setObjectName("function_tbtn"); btn->resize(48, 48); btn->setCheckable(true); btn->setChecked(false); if (type == 1) { btnGroup_1->addButton(btn,type); } else if (type == 2) { btnGroup_2->addButton(btn, type); } QGridLayout* grid = new QGridLayout; grid->addWidget(btn, 0, 0, Qt::AlignHCenter); QLabel* textlab = new QLabel(text); textlab->setObjectName("textLab"); grid->addWidget(textlab, 1, 0, Qt::AlignHCenter); QWidget* wid = new QWidget; wid->setLayout(grid); return wid; } private: QButtonGroup* btnGroup_1 = nullptr; QButtonGroup* btnGroup_2 = nullptr; QList<QButtonGroup*> ls; QToolBox* toolBox = nullptr; int preToolBoxIndex = 0; int curToolBoxIndex = 0; }; int main(int argc, char* argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); }
内容的提问来源于stack exchange,提问作者hugeYlh
相关产品推荐
相关产品推荐

