QT ③ 单|复选框 & 下拉菜单 & 列表 & 弹窗

一、单选 & 复选框

  • QCheckBox 复选框控件

    • 描述:一般使用多个复选框,以供用户提供选择

    • 常用方法:

      • setCheckState():该函数可以设置复选框的选中状态等,参数为枚举类型

        Qt::Unchecked——未选中状态

        Qt::Checked——选中状态

      • setText():该函数用于设置复选框显示的文本信息参数QString

      • isChecked():该函数用于获取复选框是否选取,返回值为true | false


  • QRadioBox 单选框控件
    • 描述:单选框,使用中会出现一个问题,Widget窗口中,单选框默认是只可以选取一个的,这时候我们想要让多组单选框都可以分组选取,就必须要用到Containers中的容器组件——Group Box,该组件可以将多个控件(不仅仅局限于单选框)加入进容器内,实现分组,每组的控件之间互不干扰。
    • 常用方法:与CheckBox大体类似

  • 单/复选 的信号问题:可以使用toggled信号实现,该信号由QAbstractButton抽象基类提供,toggled 信号通常在按钮的切换状态发生变化时触发,可以用到单、复选框上。

  • QGroupBox 容器控件
    • 描述:如上文RadioBox所讲,这个容器有很多用处,其中就可以用来将单选框分组(实现多个组别,每个组别都可以选取各自的单选框)。
    • 使用方法:
      • children():该方法继承自QObject,可以获取复杂组件中,包含的所有子组件,函数的返回值为QObjectList列表,在GroupBox这里我们就可以通过children()函数来获取列表,再进行类型转换为需要的控件类型(示例转为的类型为单选框),对其进行相关操作。
    • 使用示例:
//children 获取groupbox这个控件的所有子组件(这里是按钮)
QObjectList list = ui->groupBox_1->children();
    for(int i = 0 ; i < list.size() ; i++)
    {
        QRadioButton *rad = static_cast<QRadioButton *>(list[i]);
        if(rad->isChecked())
        {
            score += rad->text().left(1) == "C" ? 50 : 0;
        }
    }

以上组件示例代码:

#include "mycheckbox.h"
#include "ui_mycheckbox.h"

MyCheckBox::MyCheckBox(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MyCheckBox)
{
    ui->setupUi(this);

    //ui->checkBox->setChecked(true); //设置复选框 是否被勾选
    ui->checkBox->setCheckState(Qt::Checked);   //设置复选框勾选状态
    ui->checkBox->setText("自动登录");      //设置文本

    //绑定信号与槽
    connect(ui->checkBox , &QCheckBox::checkStateChanged , this , [&](Qt::CheckState state){
        if(state == Qt::Checked)
            qDebug() << "勾选";
        else if(state == Qt::Unchecked)
            qDebug() << "未勾选";
        //获取当前checkbox的状态信号
        qDebug() << ui->checkBox->checkState();
    });


    ui->radioButton->setChecked(true);  //单选框设置选择状态
    //绑定信号与槽    按钮选中状态被更改时触发
    connect(ui->radioButton , &QRadioButton::toggled , this , [&](bool flag){
        if(flag)
            qDebug() << "单选按钮被选中";
        else
            qDebug() << "单选按钮取消选中";
    });



}

MyCheckBox::~MyCheckBox()
{
    delete ui;
}

void MyCheckBox::on_pushButton_clicked()
{
    int score = 0;
    //children 获取groupbox这个控件的所有子组件(这里是按钮)
    QObjectList list = ui->groupBox_1->children();
    for(int i = 0 ; i < list.size() ; i++)
    {
        QRadioButton *rad = static_cast<QRadioButton *>(list[i]);
        if(rad->isChecked())
        {
            score += rad->text().left(1) == "C" ? 50 : 0;
        }
    }

    QObjectList list2 = ui->groupBox_2->children();
    QString q2;
    for(QObject *obj : list2)
    {
        QCheckBox *cb = static_cast<QCheckBox *>(obj);
        if(cb->isChecked())
        {
            q2.append(cb->text().left(1));
        }
    }
    if(q2 == "ABD")
        score += 50;
    ui->label->setText("成绩:" + QString::number(score));
}

UI界面

alt

二、下拉菜单(QComboBox & QMenu)

  • QComboBox 下拉栏
    • 描述:实现下拉样式的选择栏
    • 常用方法:
//添加项
void addItems(const QStringList &texts)
//从index索引处插入项  索引从0开始
void insertItems(int index, const QStringList &list)
//获取当前选项的索引   索引从0开始
int currentIndex() const
//获取当前选项的文本
QString currentText() const

  • QMenu 菜单栏

    • 描述:可以与QPushButton联用,pushbutton->setMenu() 使用该方法,可以使按钮点击后显示菜单项(与下拉菜单类似),也可以在MainWindow布局中的MenuBar中使用。

    • 具体使用:

      添加项、子菜单等方法

/**
 * @brief 向当前 QWidget(或其派生类,如 QMenu、QToolBar 等)中添加一个动作(QAction)
 * 
 * 当在 QMenu 中使用此函数时,会将传入的 QAction 对象作为一个菜单项添加到菜单中,
 * 用户点击该菜单项时会触发 QAction 的 triggered() 信号,从而执行关联的操作。
 * 
 * @param action 要添加的 QAction 指针,包含菜单项的文本、图标、快捷键、响应逻辑等信息
 * 
 * 注意:
 * - 添加的 QAction 所有权仍归原创建者,QWidget 仅负责显示和触发,不管理其生命周期
 * - 在 QMenu 中,动作会以菜单项形式显示,自动包含其设置的图标(setIcon())、文本(setText())和快捷键(setShortcut())
 * - 可通过 QAction 的 setCheckable()、setEnabled() 等方法控制菜单项的状态(如是否可勾选、是否禁用)
 * - 同一 QAction 可被添加到多个部件(如同时添加到菜单和工具栏),共享相同的状态和响应逻辑
 */
void QWidget::addAction(QAction *action);


/**
 * @brief 向当前菜单中添加一个已存在的子菜单
 * 
 * 该函数用于将一个已经创建好的 QMenu 对象作为子菜单添加到当前菜单中,
 * 实现菜单的层级嵌套。添加后,子菜单的所有权仍由调用者管理(需确保生命周期有效)。
 * 
 * @param menu 指向已创建的 QMenu 对象的指针,作为子菜单添加
 * @return 返回添加的子菜单指针(与传入的 menu 相同),便于链式调用或后续操作
 */
QAction *addMenu(QMenu *menu);

/**
 * @brief 创建并添加一个带标题的子菜单
 * 
 * 该函数会自动创建一个新的 QMenu 对象,使用指定的标题,然后将其添加为当前菜单的子菜单。
 * 新创建的子菜单所有权由当前菜单接管,无需手动释放内存。
 * 
 * @param title 子菜单的显示标题(会显示在菜单列表中)
 * @return 返回新创建的 QMenu 对象指针,可用于进一步向该子菜单添加菜单项或子菜单
 */
QMenu *addMenu(const QString &title);

/**
 * @brief 向菜单或工具栏中添加一个分隔标题(分组标签)
 * 
 * 该函数用于在菜单或工具栏中添加一个不可点击的分隔标题,主要用于对菜单项或工具按钮进行分组归类,
 * 增强界面的层次感和可操作性。分隔标题通常以加粗或特殊样式显示,与普通可交互项区分开。
 * 
 * @param text 分隔标题的显示文本,用于描述其后一组项的功能类别(例如"文件操作"、"编辑工具"等)
 * @return 返回一个与该分隔标题关联的 QAction 指针,通常无需对其进行额外操作,
 *         主要用于框架内部管理该分隔项的显示和位置
 */
QAction *addSection(const QString &text);

​ 菜单项信号示例:

QMenu *menu = new QMenu;
    QAction *act1 = menu->addAction("新建");  //向菜单中新加菜单项
    QAction *act2 = menu->addAction("保存");
    act1->setShortcut(QKeySequence("ctrl+n")); //设置快捷键
    act2->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_S));	//快捷键方法2
//绑定信号与匿名槽函数
connect(act1 , &QAction::triggered , this , [&](){
        ui->textBrowser->append("新建...");
});
//绑定信号与匿名槽函数
connect(act2 , &QAction::triggered , this , [&](){
        ui->textBrowser->append("保存...");
});

整体示例:

#include "mycombo_box.h"
#include "ui_mycombo_box.h"

MyCombo_Box::MyCombo_Box(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MyCombo_Box)
{
    ui->setupUi(this);

    ui->comboBox->setEditable(false);
    ui->comboBox->addItem("1111");
    ui->comboBox->addItem("2222");

    //定义初始化字符串列表
    //QStringList list = {"3333","44444444","5555"};
    //list << "666666";   //追加插入新的字符串到 字符串列表内

    QMenu *menu = new QMenu;
    QAction *act1 = menu->addAction("新建");  //向菜单中新加菜单项
    QAction *act2 = menu->addAction("保存");
    act1->setShortcut(QKeySequence("ctrl+n")); //设置快捷键
    act2->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_S));

    menu->addSeparator();   //添加分割线

    ui->pushButton_4->setMenu(menu);    //设置按钮菜单

    connect(act1 , &QAction::triggered , this , [&](){
        ui->textBrowser->append("新建...");
    });

    connect(act2 , &QAction::triggered , this , [&](){
        ui->textBrowser->append("保存...");
    });

}

MyCombo_Box::~MyCombo_Box()
{
    delete ui;
}



//新增
void MyCombo_Box::on_pushButton_clicked()
{
    ui->comboBox->addItem(ui->lineEdit->text());
    ui->textBrowser->append("用户新增:" + ui->lineEdit->text());
}


void MyCombo_Box::on_pushButton_2_clicked()
{
    ui->comboBox->insertItem(ui->lineEdit_2->text().toInt(),ui->lineEdit->text());
    ui->textBrowser->append("用户新增:" + ui->lineEdit->text());
}


void MyCombo_Box::on_pushButton_3_clicked()
{
    int index = ui->comboBox->currentIndex();
    //current Text获取当前文本
    ui->textBrowser->append("用户删除:" + ui->comboBox->currentText());
    ui->comboBox->removeItem(index);
}


void MyCombo_Box::on_comboBox_currentIndexChanged(int index)
{
    ui->textBrowser->append("用户选择:" + ui->comboBox->itemText(index));
}

//按钮触发式 菜单
void MyCombo_Box::on_pushButton_4_clicked()
{
    ui->pushButton_4->showMenu();
}


示例UI展示

​ 下拉菜单:

alt

​ 按钮菜单:

alt

三、QListWidget

1. QListWidget

  • 作用:提供一个可显示多个条目的项的列表控件,是一种便捷的列表容器。
  • 功能
    • 可添加、删除、排序列表项
    • 支持单选、多选等选择模式
    • 可设置列表为水平 / 垂直布局
    • 提供信号(如项被点击、选择变化等)用于交互响应
  • 特点:是一种 "即开即用" 的列表控件,无需自定义模型,适合快速实现简单列表功能。

2. QListWidgetItem

  • 作用:表示 QListWidget 中的单个列表项,用于存储列表项的内容和属性。
  • 功能
    • 可设置文本、图标、复选框等
    • 支持设置项的状态(如选中、禁用)
    • 可存储自定义数据(通过 setData()
  • 特点:是 QListWidget 的 "子元素",每个项独立管理自身的显示和数据。

典型用法

// 创建列表控件
QListWidget *listWidget = new QListWidget;

// 创建列表项并添加到列表中
QListWidgetItem *item1 = new QListWidgetItem("项1");
item1->setIcon(QIcon("icon.png")); // 设置图标
listWidget->addItem(item1);

// 直接添加文本项(内部会自动创建QListWidgetItem)
listWidget->addItem("项2");

// 显示列表
listWidget->show();

四、对话框

1.文件对话框

1. QFileDialog::getOpenFileNames()

  • 功能:弹出文件选择对话框,允许用户选择多个已有文件(用于打开操作)。

  • 返回值QStringList,包含所有选中文件的完整路径;若用户取消,则返回空列表。

  • 典型场景:批量打开文件(如图片浏览器选择多张图片、文本编辑器打开多个文档)。

  • 示例参数

    QStringList files = QFileDialog::getOpenFileNames(
        this,                  // 父窗口
        "选择文件",            // 对话框标题
        "/home",               // 默认路径
        "文本文件 (*.txt);;所有文件 (*)"  // 文件过滤器
    );
    

2. QFileDialog::getSaveFileName()

  • 功能:弹出文件保存对话框,允许用户指定单个文件的保存路径和名称

  • 返回值QString,选中的文件路径;若用户取消,则返回空字符串。

  • 典型场景:保存文件时让用户指定位置(如文本编辑器保存文档、图像软件导出图片)。

  • 示例参数

    QString file = QFileDialog::getSaveFileName(
        this,
        "保存文件",
        "/home/untitled.txt",  // 默认文件名
        "文本文件 (*.txt);;所有文件 (*)"
    );
    

关键区别

  • 数量getOpenFileNames() 支持多选文件(返回列表);getSaveFileName() 用于单个文件保存(返回单个路径)。
  • 用途:前者用于 "打开" 已有文件,后者用于 "保存" 新文件(若指定路径文件已存在,会提示是否覆盖)。

2.消息对话框

主要特点:

  • 便捷性:提供静态函数直接创建常见对话框,无需复杂配置。
  • 多类型:支持多种消息类型,如信息提示(Information)、警告(Warning)、错误(Critical)、询问(Question)等,每种类型有对应图标。
  • 交互性:可包含按钮(如 "确定"、"取消"、"是"、"否"),并返回用户点击的按钮结果。
// 信息提示框
QMessageBox::information(this, "提示", "操作完成!");
// 确认对话框(判断用户选择)
if (QMessageBox::question(this, "确认", "是否删除文件?", 
                         QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
    // 用户选择"是",执行删除
}
// 错误提示框
QMessageBox::critical(this, "错误", "文件打开失败!");

3.输入提示框

主要功能:

  • 支持多种输入类型:文本(单行 / 多行)、整数、浮点数、下拉列表选项等。
  • 可设置输入提示、默认值、范围限制(如数字的最小值 / 最大值)。
  • 返回用户输入的结果及操作状态(确认或取消)。

常见用法示例:

// 获取单行文本
bool ok;
QString text = QInputDialog::getText(this, "输入", "请输入姓名:", 
                                    QLineEdit::Normal, "", &ok);
if (ok && !text.isEmpty()) {
    // 处理用户输入的文本
}

// 获取整数
int num = QInputDialog::getInt(this, "输入", "请输入数量:", 
                              10, 1, 100, 1, &ok); // 默认10,范围1-100
if (ok) {
    // 处理整数
}

// 从下拉列表选择
QStringList items = {"选项1", "选项2", "选项3"};
QString item = QInputDialog::getItem(this, "选择", "请选择一项:", 
                                    items, 0, false, &ok);
if (ok) {
    // 处理选中项
}

特点:

  • 静态函数为主,无需手动创建对话框实例,直接调用即可。
  • 通过 bool* 参数(如 &ok)判断用户是点击了 “确认” 还是 “取消”。
  • 可根据需求自定义输入框样式(如密码框、限制输入格式等)。

4.调色板和字体设置对话框

//颜色对话框
void Widget::on_pushButton_4_clicked()
{
    //打开调色板 返回值是color类型
    QColor color = QColorDialog::getColor();
    if(!color.isValid())
        return;
    ui->textEdit->setTextColor(color);
}

//字体对话框
void Widget::on_pushButton_5_clicked()
{
    bool ok;
    QFont font = QFontDialog::getFont(&ok,QFont("宋体",28,2));
    if(ok)
        ui->textEdit->setFont(font);
}