QCheckBoxQt框架中用于创建复选框的类
它和单选按钮很相似,单选按钮常用在 “多选一” 的场景,而复选按钮常用在 “多选多”的场景
比如喜欢的水果选项中,可以在 “苹果/香蕉/桔子/葡萄” 中选择多个

1. 效果演示

选择喜欢的水果:“全选” 复选框和 “苹果/香蕉/桔子/葡萄” 这4个按钮联动

  • 点击全选按钮:可以全部选中和取消选中4种水果
  • 点击4种水果按钮:根据4种水果的选中状态(全选/全不选/部分选中),全选按钮状态设置为选中/非选中/半选

chk

2. 属性和方法

QCheckBox有很多属性,完整的可查看帮助文档。这里列出常用的属性和方法

2.1 文本

这两个是其父类QAbstractButton中的属性和方法,因此QPushButtonQRadioButtonQCheckBox都具有该属性

// 获取和设置显示的文本
QString text() const
void setText(const QString &text)

2.2 三态

单选按钮,有选中(Checked)和非选中(UnChecked)这两种状态。而复选按钮可以有三种状态:

枚举 含义
Qt::Checked 选中
Qt::Unchecked 未选中
Qt::PartiallyChecked 半选中,比如当一组复选按钮中只选择了部分时,可以设置其父项为半选状态

这三种状态对应的效果,如下:

效果1 薪资2 薪资2

可以设置复选按钮,是否支持三态,如下:

// 用于获取和设置是否支持三态
bool isTristate() const
void setTristate(bool y = true)

如果不支持三态,则使用方法单选按钮一样,只有选中和未选中两种状态,没有半选中状态
此时使用如下方法获取和设置复选按钮的选中状态,如下:

// 获取和设置复选按钮是否选中:checked/unchecked
bool isChecked() const
void setChecked(bool)

如果支持三态,则除了选中和未选中两种状态,还有半选中状态
此时使用如下方法获取和设置复选按钮的选中状态:

// 设置和获取复选按钮的状态
Qt::CheckState checkState() const
void setCheckState(Qt::CheckState state)

2.3 自动排他

复选按钮同样可以设置是否自动排他

// 获取和设置自动排他
bool autoExclusive() const
void setAutoExclusive(bool)

由于复选按通常实现的是 “多选多”,因此复选按钮的该属性默认是禁能的
qt-base

尽管在技术上可以通过复选框来实现单选框的行为,也可以通过单选框来实现复选框的行为,但还是强烈建议使用众所周知的约定。

2.4 信号槽

按钮在按下和抬起的过程中,会发射多个信号。

// 复选按钮 QCheckBox 被点击时,会发出该信号
void clicked();

// 当复选按钮的选中状态发生改变时,会发射该信号
// 所谓状态改变,是指在 UnChecked/PartiallyChecked/Checked 之间状态改变
void checkStateChanged(Qt::CheckState state)

3. 从零实现

从零写代码实现整体效果,以演示复选框的属性以及信号槽的用法

3.1 布局

UI设计师界面,拖拽对应的控件,修改显示的文字、控件的名称,然后完成布局
qt-base

说明:以上将MyWidget窗口的字体大小修改为14,有多种修改方式

方式一:在右侧的属性窗口中修改Point Size属性

方式二:通过QFont

#include <QFont>

MyWidget::MyWidget(QWidget* parent) : QWidget(parent), ui(new Ui::MyWidget) {
    // ...
    QFont font = this->font();
    font.setPointSize(14);
    this->setFont(font);
}

方式三:通过样式表

MyWidget::MyWidget(QWidget* parent) : QWidget(parent), ui(new Ui::MyWidget) {
    // ...
    this->setStyleSheet("QWidget { font-size: 18px; }");
}

3.2 代码实现

首先,在mywidget.h中添加槽函数,如下:

class MyWidget : public QWidget {

private slots:
    void on_chkAll_clicked();
    void onStateChanged();
};

然后,来到mywidget.cpp中实现这两个槽函数,如下:

void MyWidget::on_chkAll_clicked() {
    // 这里需要将“全选”按钮的三态设置为false,也就是不允许出现半选状态
    // 三态:Unchecked->PartiallyChecked->Checked->Unchecked,如此循环
    // 非三态:Unchecked->Checked->Unchecked,如此循环
    qDebug() << ui->chkAll->checkState();
    ui->chkAll->setTristate(false);
    qDebug() << ui->chkAll->checkState();

    bool checked = ui->chkAll->isChecked();
    ui->chkApple->setChecked(checked);
    ui->chkBanana->setChecked(checked);
    ui->chkOrange->setChecked(checked);
    ui->chkGrape->setChecked(checked);
}

void MyWidget::onStateChanged() {
    QString s;

    bool appleChecked = ui->chkApple->isChecked();
    bool bananaChecked = ui->chkBanana->isChecked();
    bool orangeChecked = ui->chkOrange->isChecked();
    bool grapeChecked = ui->chkGrape->isChecked();

    if ( appleChecked && bananaChecked && orangeChecked && grapeChecked ) {
        // 全部选中
        ui->chkAll->setCheckState(Qt::Checked);
    } else if ( !(appleChecked || bananaChecked || orangeChecked || grapeChecked) ) {
        // 全部未选中
        ui->chkAll->setCheckState(Qt::Unchecked);
    } else {
        // 部分选中
        ui->chkAll->setCheckState(Qt::PartiallyChecked);
    }

    if ( appleChecked ) {
        s += ui->chkApple->text() += " ";
    }

    if ( bananaChecked ) {
        s += ui->chkBanana->text() += " ";
    }

    if ( orangeChecked ) {
        s += ui->chkOrange->text() += " ";
    }

    if ( grapeChecked ) {
        s += ui->chkGrape->text();
    }

    ui->lineEditSelected->setText(s);
}

最后,在构造函数中关联信号槽,如下:

MyWidget::MyWidget(QWidget* parent) : QWidget(parent), ui(new Ui::MyWidget) {

    // 4个复选按钮对应同一个槽函数
    connect(ui->chkApple, &QCheckBox::checkStateChanged, this, &MyWidget::onStateChanged);
    connect(ui->chkBanana, &QCheckBox::checkStateChanged, this, &MyWidget::onStateChanged);
    connect(ui->chkOrange, &QCheckBox::checkStateChanged, this, &MyWidget::onStateChanged);
    connect(ui->chkGrape, &QCheckBox::checkStateChanged, this, &MyWidget::onStateChanged);
}

4. 点赞、获取源码

看到这里的小伙伴,去B站给明王一个【免费的点赞】吧,你的支持,是我持续更新优质内容的动力,感谢~

源码下载地址
链接: https://pan.baidu.com/s/10ngM8uBNeed-s1FYqujfoA
提取码: ming