当前位置: 首页 > news >正文

【Qt开发】按钮类控件(二)-> QRadioButton

目录

1 -> 概念

1.1 -> 核心概念:互斥性选择

1.2 -> 视觉呈现与状态

1.3 -> 分组机制

2 -> 相关属性

3 -> 代码示例

3.1 -> 选择性别

3.2 -> click,press,release,toggled 的区别

3.3 -> 单选框分组

4 -> 总结


1 -> 概念

在构建图形用户界面(GUI)时,提供清晰、直观的选项选择机制是提升用户体验的关键。Qt 框架中的 QRadioButton(单选按钮)控件,正是为满足 “多选一” 的精确场景而设计的核心元素。它源于其物理世界原型——老式汽车收音机上的机械按钮,按下其中一个则会弹出之前被按下的那个,确保了任何时候都只有一个选项处于激活状态。

1.1 -> 核心概念:互斥性选择

QRadioButton 最根本、最重要的特性是 互斥性。这意味着在一组单选按钮中,用户只能且必须选择其中的一个选项。当一个选项被选中时,之前选中的选项会自动变为未选中状态。这种设计天然地适用于那些所有选项相互排斥、不可兼得的场景。

例如:

  • 性别选择:男 / 女 / 其他
  • 评分等级:优 / 良 / 差
  • 支付方式:信用卡 / 支付宝 / 微信支付
  • 分辨率设置:1920*1080 / 1280*720 / 800*600

这种 “非此即彼” 的交互模式,能够清晰地引导用户做出唯一选择,避免了歧义。

1.2 -> 视觉呈现与状态

一个典型的 QRadioButton 由两部分组成:

  1. 圆形指示器:一个空心的圆形,当被选中时,内部会填充一个实心圆点。

  2. 文本标签:紧邻指示器显示的描述性文字,用于明确告知用户该选项代表的意义。

它拥有两种主要状态:

  • 选中状态:圆形指示器内有一个实心点。这是该选项被激活的视觉反馈。

  • 未选中状态:圆形指示器为空心的。

此外,为了满足更复杂的需求,QRadioButton 还支持第三种状态:

  • 部分选中状态:在某些特殊情况下(例如通过 setAutoExclusive(false) 暂时关闭自动互斥),它可以被设置为一种 “未决” 或 “三态” 模式。但这是一种非典型用法,绝大多数情况下使用的是标准的选中 / 未选中两种状态。

1.3 -> 分组机制

单个 QRadioButton 本身并不具备互斥性。互斥的行为并非由按钮自身实现,而是由它们所处的 分组 所强制规定的。

Qt 提供了两种主要的分组方式:

  1. 父容器自动分组:这是最常见和简便的方法。将多个 QRadioButton 放置在同一个父控件内(例如同一个 QGroupBoxQWidget 或 QFrame),Qt 会自动识别它们属于同一逻辑组,并为其建立互斥关系。这种方式布局直观,管理方便。

  2. 使用 QButtonGroup 抽象分组:对于更复杂的界面,当单选按钮分散在不同的布局或容器中,但又属于同一个逻辑选择集时,QButtonGroup 类就变得至关重要。它是一个不可见的逻辑容器,可以将任何地方的 QRadioButton 添加进去,从而在逻辑上将它们编为一组,实现互斥选择,而不受其物理布局的限制。这提供了极大的灵活性。

2 -> 相关属性

QRadioButton 是单选按钮。可以让我们在多个选项中选择一个。

作为 QAbstractButton 和 QWidget 的子类,对于 QRadioButton 同样适用。

QAbstractButton 中和 QRadioButton 关系比较大的属性:

属性说明
checkable是否能选中
checked是否已经被选中。checkable 是 checked 的前提条件
autoExclusive

是否排他

选中一个按钮之后是否会取消其他按钮的选中

对于 QRadioButton 来说默认就是排他的

3 -> 代码示例

3.1 -> 选择性别

1. 在界面上创建一个 label,和 3个 单选按钮

设置的文本如下。3个 单选按钮的 objectName 分别为 radioButton_male、radioButton_female 和 

radioButton_other

2. 修改 widget.cpp,编辑 3个 QRadioButton 的 slot 函数

void Widget::on_radioButton_male_clicked()
{// 把界面上的 label 的内容进行更新ui->label->setText("您选择的性别为: 男");
}void Widget::on_radioButton_female_clicked()
{// 把界面上的 label 的内容进行更新ui->label->setText("您选择的性别为: 女");
}void Widget::on_radioButton_other_clicked()
{// 把界面上的 label 的内容进行更新ui->label->setText("您选择的性别为: 其他");
}

3. 运行程序,可以看到随着选择不同的单选按钮,label 中的提示文字就会随之变化

4. 当前代码中,如果程序启动,则不会选择任何选项

可以修改代码,让程序启动默认选中性别男

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 设置默认选项ui->radioButton_male->setChecked(true);ui->label->setText("您选择的性别为: 男");}Widget::~Widget()
{delete ui;
}void Widget::on_radioButton_male_clicked()
{// 把界面上的 label 的内容进行更新ui->label->setText("您选择的性别为: 男");
}void Widget::on_radioButton_female_clicked()
{// 把界面上的 label 的内容进行更新ui->label->setText("您选择的性别为: 女");
}void Widget::on_radioButton_other_clicked()
{// 把界面上的 label 的内容进行更新ui->label->setText("您选择的性别为: 其他");
}

此时运行程序,即可以看到性别男已经被选中了。

5. 当前代码中,也可以禁用 “其他” 被选中

修改 widget.cpp 的构造函数

ui->radioButton_other->setCheckable(false);

运行程序,可以看到,点击 “其他” 按钮时,虽然不会被选中,但是可以触发点击事件,使上面的 label 显示性别为其他。

使用 setEnabled 是更加彻底的禁用按钮的方式。此时该按钮无法被选中,也无法响应任何输入。

ui->radioButton_other->setEnabled(false);

3.2 -> click,press,release,toggled 的区别

  • clicked 表示一次 “点击”
  • pressed 表示鼠标 “按下”
  • released 表示鼠标 “释放”
  • toggled 表示按钮状态切换

1. 在界面上创建四个单选按钮

objectName 分别为 radioButton、radioButton_2、radioButton_3 和 radioButton_4。

2. 依次给四个单选按钮创建 clicked槽函数、pressed槽函数、released槽函数 和 toggled槽函数

#include "widget.h"
#include "ui_widget.h"#include <QDebug>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}void Widget::on_radioButton_clicked(bool checked)
{// 此处从 checked 就表示了当前 radioButton 的选中状态.qDebug() << "cliched: " << checked;
}void Widget::on_radioButton_2_pressed()
{qDebug() << "pressed";
}void Widget::on_radioButton_3_released()
{qDebug() << "released";
}void Widget::on_radioButton_4_toggled(bool checked)
{// checked 状态发生改变, 就会触发这个信号.qDebug() << "toggled: " << checked;
}

3. 运行程序,可以看到

  • clicked 是一次鼠标按下 + 鼠标释放触发的
  • pressed 是鼠标按下触发的
  • released 是鼠标释放触发的
  • toggled 是 checked 属性改变时触发的

总的来说,toggled 是最适合 QRadioButton 的。

3.3 -> 单选框分组

1. 在界面上创建 9个 单选框,用来模拟麦麦点餐界面

objectName 分别为 radioButton ~ radioButton_9

此时直接运行程序,可以看到,这 9个 QRadioButton 之间是排他的。

我们希望的是每一组的内部来控制排他,但是组和组之间不能排他。

2. 引入 QButtonGroup 进行分组

修改 widget.cpp

#include "widget.h"
#include "ui_widget.h"#include <QButtonGroup>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QButtonGroup* group1 = new QButtonGroup(this);QButtonGroup* group2 = new QButtonGroup(this);QButtonGroup* group3 = new QButtonGroup(this);group1->addButton(ui->radioButton);group1->addButton(ui->radioButton_2);group1->addButton(ui->radioButton_3);group2->addButton(ui->radioButton_4);group2->addButton(ui->radioButton_5);group2->addButton(ui->radioButton_6);group3->addButton(ui->radioButton_7);group3->addButton(ui->radioButton_8);group3->addButton(ui->radioButton_9);}Widget::~Widget()
{delete ui;
}

再次执行程序,可以看到可以按照正确的分组方式来完成排他了。

4 -> 总结

QRadioButton 是 Qt 控件库中一个功能专一而强大的组件。它通过其固有的互斥性,完美解决了需要用户进行单一选择的交互需求。其有效性不仅依赖于控件本身,更在于通过父容器或 QButtonGroup 进行合理分组的机制。在与 QCheckBox 的对比中,其应用场景的区别变得尤为清晰。最终,遵循良好的UI/UX设计原则来使用它,是构建出清晰、高效、用户友好的桌面应用程序界面的重要一环。


感谢各位大佬支持!!!

互三啦!!!


文章转载自:

http://CRVm0hCY.nqmwk.cn
http://hdOzdKZi.nqmwk.cn
http://VflTZgIB.nqmwk.cn
http://7nx2IVRW.nqmwk.cn
http://aOeT48vU.nqmwk.cn
http://CstFZRs9.nqmwk.cn
http://3DDaOoN8.nqmwk.cn
http://SHYl9vmI.nqmwk.cn
http://JP8CrrPY.nqmwk.cn
http://8kpyRFxI.nqmwk.cn
http://EuICaNwl.nqmwk.cn
http://yRqTGk5E.nqmwk.cn
http://rH2iToYv.nqmwk.cn
http://Gz5R2u8d.nqmwk.cn
http://LLgayPvK.nqmwk.cn
http://Q0p7jiE6.nqmwk.cn
http://QkFwDI61.nqmwk.cn
http://6sSvV0wn.nqmwk.cn
http://vsvEjUyI.nqmwk.cn
http://kjSUgXcZ.nqmwk.cn
http://oULfKulm.nqmwk.cn
http://0Gz6NwhY.nqmwk.cn
http://cVJy5MAz.nqmwk.cn
http://8pmtsZU1.nqmwk.cn
http://2fFlzpEo.nqmwk.cn
http://4aH9rhnC.nqmwk.cn
http://s0dAz0AT.nqmwk.cn
http://334DW81U.nqmwk.cn
http://oeyhr2fD.nqmwk.cn
http://wXPDRRHu.nqmwk.cn
http://www.dtcms.com/a/362428.html

相关文章:

  • lua脚本在redis中执行是否是原子性?
  • 每次开机弹出‘killer network manager launcher’链接无应用打开”解决方案
  • 【Lua】题目小练13
  • CodeForge v25.0.3 发布:Web 技术栈全覆盖,编辑器个性化定制新时代
  • 分页功能设计
  • Docker镜像指南:从核心命令到离线迁移实战
  • 实时视频链路的产业化路径:多场景应用与长期思考
  • 力扣:2458. 移除子树后的二叉树高度(dfs序)
  • leetcode111. 二叉树的最小深度
  • 前缀和之距离和
  • 基于SQLite的智能图片压缩存储系统:代码解析与实战应用
  • Time-MOE 音频序列分类任务
  • form表达和实体类通常有什么不同
  • C#中的克隆:从理论到实践
  • Elasticsearch Java开发(SpringBoot)
  • 从零开始的云计算生活——第五十六天,临深履薄,kubernetes模块之etcd备份恢复和集群升级指南
  • Prettier代码格式化工具测评:支持JS/TS/Vue多语言,兼容ESLint实现团队代码格式统一
  • 在 PySpark 中解锁窗口函数的力量,实现高级数据转换
  • 什么是Token?——理解自然语言处理中的基本单位
  • 毕业项目推荐:68-基于yolov8/yolov5/yolo11的水稻虫害检测识别系统(Python+卷积神经网络)
  • Python OpenCV图像处理与深度学习: Python OpenCV图像配准入门
  • 深度学习中的数据增强实战:基于PyTorch的图像分类任务优化
  • 云计算学习100天-第43天-cobbler
  • 【linux仓库】万物至简的设计典范:如何用‘文件’这一个概念操纵整个Linux世界?
  • 【数据分享】土地利用shp数据分享-内蒙古
  • Python应用——ffmpeg处理音视频的常见场景
  • 谷歌AdSense套利是什么?怎么做才能赚到钱
  • 安卓QQ闪照获取软件(支持TIM)
  • 各省市信息化项目管理办法中的网络安全等级保护如何规定的?
  • 智能化企业级CRM系统开发实战:飞算JavaAI全流程体验