Qt/C++学习系列之QButtonGroup的简单使用

前言

在练手项目中,使用了QButtonGroup。项目需求有互斥的要求,在使用QRadioButton的基础上,叠加使用QButtonGroup。通过使用了解到,除QRadioButton以外,QCheckBox也可以使用,提供统一的管理。


QButtonGroup

QButtonGroup是用于对一组按钮进行统一管理的类,可以定义多个QRadioButton或QCheckBox进行分组管理。从而确保其按钮按下的互斥逻辑或统一处理的逻辑。

刨析源码

cpp 复制代码
class Q_WIDGETS_EXPORT QButtonGroup : public QObject
{
    Q_OBJECT

    Q_PROPERTY(bool exclusive READ exclusive WRITE setExclusive)
public:
    explicit QButtonGroup(QObject *parent = Q_NULLPTR);
    ~QButtonGroup();

    void setExclusive(bool);
    bool exclusive() const;

    void addButton(QAbstractButton *, int id = -1);
    void removeButton(QAbstractButton *);

    QList<QAbstractButton*> buttons() const;

    QAbstractButton * checkedButton() const;
    // no setter on purpose!

    QAbstractButton *button(int id) const;
    void setId(QAbstractButton *button, int id);
    int id(QAbstractButton *button) const;
    int checkedId() const;

Q_SIGNALS:
    void buttonClicked(QAbstractButton *);
    void buttonClicked(int);
    void buttonPressed(QAbstractButton *);
    void buttonPressed(int);
    void buttonReleased(QAbstractButton *);
    void buttonReleased(int);
    void buttonToggled(QAbstractButton *, bool);
    void buttonToggled(int, bool);

private:
    Q_DISABLE_COPY(QButtonGroup)
    Q_DECLARE_PRIVATE(QButtonGroup)
    friend class QAbstractButton;
    friend class QAbstractButtonPrivate;
};

借助AI可以快速刨析一下源码,同时学习一下有关QButtonGroup的属性、成员函数:

  • 添加和移除按钮: addButton() 为将按钮添加到按钮组中,这里要注意(QAbstractButton *, int id = -1),id默认为-1,意味着如果在未添加按钮的情况下,直接做移除操作会出现-1的情况。 在很多时候要注意按钮组内是否有按钮,在程序编译的时候要初始化,进行按钮的添加。 removeButton() 为移除按钮。
  • 设置互斥性: setExclusive() 将分类为一组的按钮进行互斥设置。对于单选按钮组,通常设置为互斥(true),这样组内只能选择一个按钮;对于复选按钮组,通常设置为非互斥(false)。 exclusive() const:检查按钮组是否为互斥的,并反馈。
  • 获取当前选中的按钮: checkedButton() 获取当前选中的按钮。
  • 通过 ID 操作按钮 button(int id) const:通过 ID 获取按钮。 setId(QAbstractButton *button, int id):为按钮设置一个唯一的 ID。 id(QAbstractButton *button) const:获取按钮的 ID。 checkedId() const:返回当前选中按钮的 ID。如果没有按钮被选中,则返回 -1。
  • 信号和槽:(因为继承QObject,这意味着它可以使用 Qt 的信号和槽机制。) QButtonGroup 提供了一些信号,例如 buttonClicked() 和 buttonPressed(),可以用于响应按钮的点击事件。 buttonClicked(QAbstractButton *):当按钮被点击时发出信号,传递按钮的指针。 buttonClicked(int):当按钮被点击时发出信号,传递按钮的 ID。 buttonPressed(QAbstractButton *)、buttonPressed(int):当按钮被按下时发出信号。 buttonReleased(QAbstractButton *)、buttonReleased(int):当按钮被释放时发出信号。 buttonToggled(QAbstractButton *, bool)、buttonToggled(int, bool):当按钮的状态切换时发出信号(仅适用于复选按钮)。

具体使用

在项目中,需要通过不同的QRadioButton来引导后续关于QComboBox的使用。那么在项目中,我是这么处理的。

界面设计

这里我拖了QgroupBox,在里面包含了三个QRadioButton,并且在选择QRadioButton的基础上需要刷新点亮对应的QComboBox。

具体函数使用

初始化

cpp 复制代码
	boardButtonGroup = new QButtonGroup(this);
    boardButtonGroup->addButton(ui->RBtn_xz_1, 0); // ID为0
    boardButtonGroup->addButton(ui->RBtn_xz_2, 1); // ID为1
    boardButtonGroup->addButton(ui->RBtn_xz_3, 2); // ID为2
	boardButtonGroup->setExclusive(true);
    for (int i = 1; i <= 12; ++i)
    {
        ui->CB_xz_1->addItem(QString("选择2_%1").arg(i));
        ui->CB_xz_2->addItem(QString("选择3_%1").arg(i));
    }
  • 创建QButtonGroup,并给QRadioButton进行标号。
  • addItem初始化QComboBox控件的内容。
  • setExclusive设置互斥逻辑。

信号与槽函数(两种方式)

  • 脱离QButtonGroup进行控制:
cpp 复制代码
connect(ui->RBtn_xz_2, &QRadioButton::toggled, ui->CB_xz_1, &QComboBox::setEnabled);
    connect(ui->RBtn_xz_3, &QRadioButton::toggled, ui->CB_xz_2, &QComboBox::setEnabled);

这里是将QRadioButton的 toggled 信号连接到 QComboBox 的 setEnabled 槽。

  • 使用QButtonGroup
cpp 复制代码
handleButtonClicked(boardButtonGroup->checkedId());

handleButtonClicked 函数:传入当前按钮组中选中的按钮的 ID。这里的checkedId()就是使用到QButtonGroup的ID。

cpp 复制代码
QObject::connect(boardButtonGroup, QOverload<int>::of(&QButtonGroup::buttonClicked),
                     [this](int id) {
        handleButtonClicked(id);
    });

这里是QButtonGroup 的 buttonClicked 信号连接到一个 lambda 表达式中。通过捕捉到的ID来进行handleButtonClicked函数的处理。

cpp 复制代码
void MainWindow::handleButtonClicked(int id) {
    switch (id) {
        case 0: // RBtn_xz_1 被选中
            ui->CB_xz_1->setEnabled(false);
            ui->CB_xz_2->setEnabled(false);
            break;
        case 1: // RBtn_xz_2 被选中
            ui->CB_xz_1->setEnabled(true);
            ui->CB_xz_2->setEnabled(false);
            break;
        case 2: // RBtn_xz_3 被选中
            ui->CB_xz_1->setEnabled(false);
            ui->CB_xz_2->setEnabled(true);
            break;
        default:
            ui->CB_xz_1->setEnabled(false);
            ui->CB_xz_2->setEnabled(false);
            break;
    }
}

这个代码就是根据按钮的 ID 设置 QComboBox 的启用状态。

--

总结

本文从QButtonGroup的源码角度进行分析,仅仅简单介绍了QButtonGroup的使用。对于项目中的使用,两种方式那更倾向于哪一种呢?

相关推荐
sinat_267611914 小时前
Trae AI 进行 Android 从0 到 1的一键开发
kotlin·android studio·trae
阆遤1 天前
利用TRAE对nanobot进行安全分析并优化
python·安全·ai·trae·nanobot
Molesidy1 天前
【VSCode】VSCode或者Trae的扩展文件夹以及用户设置文件夹的路径更改到指定位置
ide·编辑器·trae
yosh'joy!!2 天前
下载Trae使用
ai·trae
豆包MarsCode2 天前
只需一个指令,让 OpenClaw 安排 TRAE 干活
trae
sugar15692 天前
Trae快速构建自己项目的docker镜像
docker·容器·trae
sugar15692 天前
Trae 添加项目规则,快速完成crmeb项目本地开发环境搭建
docker·容器·trae
欧简墨3 天前
kotlin Android Extensions插件迁移到viewbinding总结
android·trae
arbboter3 天前
【AI编程】约束即设计:AI时代的人机边界重构
ai编程·ai工作流·人机协作·trae·声明式执行·流程编排
进击的雷神5 天前
Trae AI IDE 完全指南:从入门到精通
大数据·ide·人工智能·trae