Qt 对话框全方面详解,包含示例与解析

文章目录

  • [1. 对话框](#1. 对话框)
    • [1.1 对话框介绍](#1.1 对话框介绍)
    • [1.2 对话框的创建](#1.2 对话框的创建)
    • [1.3 对话框的内存释放](#1.3 对话框的内存释放)
    • [1.4 自定义对话框](#1.4 自定义对话框)
    • [1.5 模态对话框](#1.5 模态对话框)
    • [1.6 非模态对话框](#1.6 非模态对话框)
    • [1.7 内置对话框](#1.7 内置对话框)
      • [1.7.1 消息对话框 QMessageBox](#1.7.1 消息对话框 QMessageBox)
      • [1.7.2 文件对话框 QFileDialog](#1.7.2 文件对话框 QFileDialog)
      • [1.7.3 输入对话框 QInputDialog](#1.7.3 输入对话框 QInputDialog)
      • [1.7.4 字体对话框 QFontDialog](#1.7.4 字体对话框 QFontDialog)
      • [1.7.5 进度对话框 QProgressDialog](#1.7.5 进度对话框 QProgressDialog)
      • [1.7.6 颜色对话框 QColorDialog](#1.7.6 颜色对话框 QColorDialog)

1. 对话框

1.1 对话框介绍

对话框是 GUI 程序中不可或缺的组成部分。⼀些不适合在主窗⼝实现的功能组件可以设置在对话框

中。对话框通常是⼀个顶层窗⼝,出现在程序最上层,⽤于实现短期任务或者简洁的⽤⼾交互。Qt常

⽤的内置对话框有:QFiledialog(⽂件对话框)、QColorDialog(颜⾊对话框)、QFontDialog
(字体对话框)、QInputDialog (输⼊对话框)和 QMessageBox(消息框)

1.2 对话框的创建

在Qt中创建一个对话框项目:

cpp 复制代码
//dialog.cpp
Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    ui->setupUi(this);
}

Dialog::~Dialog()
{
    delete ui;
}
//main.cpp
#include "dialog.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Dialog w;
    w.show();
    return a.exec();
}

可以看到,页面风格与QWidget极其类似。

1.3 对话框的内存释放

  • 创建一个dialog,由于继承Widget所以可以设置标题和大小,通过 show 设置为可见,注意通过 setattribute 来设置关闭时自动销毁dialog,防止内存泄漏。
cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

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


void MainWindow::on_pushButton_clicked()
{
    QDialog* dialog=new QDialog(this);
    //继承QWidget的接口设置标题和大小
    dialog->setWindowTitle("这是一个对话框");
    dialog->resize(500,200);
    //设置show
    dialog->show();
    //设置关闭时释放内存,防止内存泄漏
    dialog->setAttribute(Qt::WA_DeleteOnClose);
}

1.4 自定义对话框

  1. 通过代码纯手搓 Dialog
  • 先创建一个C++ 类,类名为 Dialog,继承自QDialog

  • 再通过 parent 初始化 QDialog,创建布局管理器,添加两个控件,这样就可以代替QDialog的所有功能。
cpp 复制代码
Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
{
    QVBoxLayout* layout = new QVBoxLayout();
	this->setLayout(layout);
	
	QLabel* labal = new QLabel("这是一个对话框",this);
	QPushButton* button = new QPushButton("关闭",this);
	
	layout->addWidget(labal);
	layout->addWidget(button);
	
	connect(button,&QPushButton::clicked,this,&Widget::handle);
}

Dialog::~Dialog()
{
}

void Widget::handle()
{
    this->close();
}
  1. 通过ui创建
  • 选择创建 dialog without button,后在 dialog.ui 中拖动pushbutton,创建按钮,转到槽函数,完成相应操作:


cpp 复制代码
Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
}

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

void Dialog::on_pushButton_clicked()
{
    this->close();
}

1.5 模态对话框

  1. 核心定义 :模态对话框显示后会阻塞其父窗口(及整个应用相关交互),用户必须先关闭/处理完该对话框,才能回到父窗口进行任何操作。

  2. 核心特征

    • 阻塞性:对话框显示期间,父窗口无法被点击、输入、拖拽等任何交互操作;
    • 代码执行逻辑:调用显示函数后,代码会阻塞在该函数处,直到对话框关闭,才继续执行后续代码。
  3. 代码示例

cpp 复制代码
dialog->exec();//创建对话框,指定exec即可

1.6 非模态对话框

  1. 核心定义 :非模态对话框显示后不会阻塞父窗口,用户可同时操作对话框和父窗口,属于"并行交互"的对话框类型。

  2. 核心特征

    • 非阻塞性:对话框显示后,父窗口仍可正常点击、输入、拖拽等交互;
    • 代码执行逻辑:调用显示函数后,代码会立刻返回,无需等待对话框关闭,直接执行后续逻辑。
  3. 代码示例

cpp 复制代码
dialog->show();//常规创建对话框即可,(默认为非模态对话框)

1.7 内置对话框

Qt 内置对话框(也叫 "标准对话框")是 Qt 提供的现成、可复用的对话框类型,全部继承自QDialog类(遵循统一的对话框基类规范)

对话框类名 功能描述 典型使用场景
QMessageBox 消息提示、提问、警告、错误 操作确认、信息通知、异常提示
QFileDialog 文件/文件夹选择、文件保存 打开文件、选择文件夹、保存文件
QInputDialog 获取用户输入(文本/数值) 输入用户名、设置数值参数
QFontDialog 字体/字号/样式选择 文本编辑器的字体设置
QPrintDialog 打印参数设置、打印机选择 文档/内容打印
QProgressDialog 显示任务进度、支持取消操作 文件下载、数据处理等耗时任务

1.7.1 消息对话框 QMessageBox

  • 作用:用于向用户提示信息、强制用户选择操作(模态显示),是最常用的内置对话框。
  • 使用示例
    • messagebox提供了一系列Icon枚举常量:
cpp 复制代码
enum Icon {
    // keep this in sync with QMessageDialogOptions::Icon
    NoIcon = 0,          // 无图标:对话框不显示任何图标,仅展示文本和按钮
    Information = 1,     // 信息图标:显示蓝色圆形"i"图标,用于提示程序正常运行的普通信息(如操作完成、状态通知)
    Warning = 2,         // 警告图标:显示黄色三角形"!"图标,用于提示非关键性错误(如参数不合法但不影响程序运行)
    Critical = 3,        // 严重错误图标:显示红色圆形"×"图标,用于提示严重错误(如文件损坏、权限不足等可能导致程序异常的场景)
    Question = 4         // 提问图标:显示蓝色圆形"?"图标,用于向用户发起提问(如确认是否保存、是否退出等需要用户选择的场景)
};
  • 还提供了一些按钮常量:
cpp 复制代码
enum StandardButton {
    // keep this in sync with QDialogButtonBox::StandardButton and QPlatformDialogHelper::StandardButton
    NoButton           = 0x00000000,    // 无按钮:对话框不显示任何按钮,仅用于纯提示场景
    Ok                 = 0x00000400,    // 确定按钮:通用确认操作(如确认提示、完成操作)
    Save               = 0x00000800,    // 保存按钮:用于保存当前修改的内容(如文档、配置)
    SaveAll            = 0x00001000,    // 全部保存按钮:批量保存所有修改的内容(如多文档编辑)
    Open               = 0x00002000,    // 打开按钮:用于选择并打开文件/文件夹
    Yes                = 0x00004000,    // 是按钮:回答提问类对话框的肯定选择(如"是否删除?"选"是")
    YesToAll           = 0x00008000,    // 全部是按钮:批量操作的肯定选择(如"是否全部覆盖?"选"全部是")
    No                 = 0x00010000,    // 否按钮:回答提问类对话框的否定选择(如"是否删除?"选"否")
    NoToAll            = 0x00020000,    // 全部否按钮:批量操作的否定选择(如"是否全部覆盖?"选"全部否")
    Abort              = 0x00040000,    // 终止按钮:终止当前正在执行的任务(如文件下载、数据处理)
    Retry              = 0x00080000,    // 重试按钮:重新执行失败的任务(如网络请求失败后重试)
    Ignore             = 0x00100000,    // 忽略按钮:忽略当前错误/提示,继续执行后续操作(非终止/重试)
    Close              = 0x00200000,    // 关闭按钮:关闭对话框(无额外操作,仅关闭窗口)
    Cancel             = 0x00400000,    // 取消按钮:取消当前操作并关闭对话框(如取消文件选择、取消保存)
    Discard            = 0x00800000,    // 放弃按钮:放弃当前修改的内容(区别于Cancel,强调"丢弃内容")
    Help               = 0x01000000,    // 帮助按钮:打开相关操作的帮助文档/提示
    Apply              = 0x02000000,    // 应用按钮:应用当前设置但不关闭对话框(如属性面板修改后即时生效)
    Reset              = 0x04000000,    // 重置按钮:将设置恢复到对话框打开时的初始状态
    RestoreDefaults    = 0x08000000,    // 恢复默认值按钮:将设置恢复到程序默认配置(区别于Reset)

    FirstButton        = Ok,            // 内部使用:标记第一个有效标准按钮(无需开发者调用)
    LastButton         = RestoreDefaults,// 内部使用:标记最后一个有效标准按钮(无需开发者调用)

    YesAll             = YesToAll,      // 已废弃:兼容旧版本,等效于YesToAll,建议使用YesToAll
    NoAll              = NoToAll,       // 已废弃:兼容旧版本,等效于NoToAll,建议使用NoToAll

    Default            = 0x00000100,    // 已废弃:标记默认按钮(原用于设置回车默认触发的按钮)
    Escape             = 0x00000200,    // 已废弃:标记ESC键触发的按钮(原用于设置ESC默认触发的按钮)
    FlagMask           = 0x00000300,    // 已废弃:掩码值,用于分离按钮标识和标志位
    ButtonMask         = ~FlagMask      // 已废弃:掩码值,用于提取纯按钮标识(排除标志位)
};
cpp 复制代码
QMessageBox* messagebox=new QMessageBox(this);
messagebox->setText("对话框文本");
messagebox->setWindowTitle("对话框标题");
messagebox->setIcon(QMessageBox::Question);
messagebox->setStandardButtons(QMessageBox::Ok|QMessageBox::Cancel);

messagebox->exec();//常用设置为模态对话框

messagebox->setAttribute(Qt::WA_DeleteOnClose);
  • 快速创建:

    QMessageBox 提供了一系列静态成员函数 ,用于快速创建不同类型的模态对话框 ,会自动设置对应图标、默认按钮,并以模态方式显示。

    • 以QMessageBox::question为例
    cpp 复制代码
    QMessageBox::StandardButton question(
        QWidget *parent,        // 父窗口(对话框会模态关联到该窗口)
        const QString &title,   // 对话框标题
        const QString &text,    // 对话框显示的文本内容
        QMessageBox::StandardButtons buttons = QMessageBox::Ok | QMessageBox::Cancel, // 按钮组合(默认"确定+取消")
        QMessageBox::StandardButton defaultButton = QMessageBox::NoButton // 默认聚焦的按钮
    );
    • 返回值 :用户点击的按钮(QMessageBox::Ok/QMessageBox::Cancel等)。
    • 示例
    cpp 复制代码
    // 弹出模态对话框,用户选择"Ok"或"Cancel"
    QMessageBox::StandardButton res = QMessageBox::question(
        this, "对话框标题", "对话框文本", 
        QMessageBox::Ok | QMessageBox::Cancel
    );
    // 根据用户选择执行逻辑
    if (res == QMessageBox::Ok) {
        qDebug() << "用户点击了确定";
    } else {
        qDebug() << "用户点击了取消";
    }
    • QMessageBox::information、QMessageBox::warning、QMessageBox::critical、QMessageBox::about、QMessageBox::aboutQt 均类似。
  • 自定义按钮:利用QMessageBoxaddButton()方法添加自定义按钮:

cpp 复制代码
addButton(const QString &text, QMessageBox::ButtonRole role)
cpp 复制代码
enum ButtonRole {
        // keep this in sync with QDialogButtonBox::ButtonRole and QPlatformDialogHelper::ButtonRole
        InvalidRole = -1,
        AcceptRole,
        RejectRole,
        DestructiveRole,
        ActionRole,
        HelpRole,
        YesRole,
        NoRole,
        ResetRole,
        ApplyRole,

        NRoles
    };

常用ButtonRole类型

  • QMessageBox::AcceptRole:确认类按钮(如"确定",默认按Enter触发);
  • QMessageBox::RejectRole:取消类按钮(如"取消",默认按Esc触发);
  • QMessageBox::ActionRole:普通操作类按钮(如"更多")。
cpp 复制代码
 messagebox->addButton(new QPushButton("按钮",messagebox),QMessageBox::AcceptRole);
  • 通过模态对话框的返回值判断用户操作:
cpp 复制代码
  int ret=messagebox->exec();
  if(ret==QMessageBox::Ok) handler();

1.7.2 文件对话框 QFileDialog

QFileDialog是Qt提供的文件对话框组件,用于实现打开外部文件将内容保存到外部文件的功能。介绍 3 个核心静态方法:

  • parent:对话框的父窗口(决定对话框的显示位置等);
  • caption:对话框的标题(比如"打开文件""保存文件");
  • dir:默认打开的文件夹路径(比如设置为"C:/",打开对话框时默认显示C盘);
  • filter:文件过滤器(比如只显示txt文件,可写为"文本文件 (*.txt);;所有文件 (*.*)")。
  1. 打开单个文件

    cpp 复制代码
    QString getOpenFileName(
        QWidget *parent = nullptr,       // 父窗口(默认无)
        const QString &caption = QString(), // 对话框标题(默认空)
        const QString &dir = QString(),     // 默认打开的路径(默认空)
        const QString &filter = QString(),  // 文件过滤器(默认空)
        QString *selectedFilter = nullptr,  // 选中的过滤器(默认空)
        QFileDialog::Options options = Options() // 对话框选项(默认无)
    )

    弹出文件选择框,只能选一个文件,返回选中文件的路径(QString类型)。

  2. 打开多个文件

    cpp 复制代码
    QStringList getOpenFileNames(
        // 参数同getOpenFileName
    )

    弹出文件选择框,可以选多个文件,返回选中文件的路径列表(QStringList类型)。

  3. 保存文件

    cpp 复制代码
    QString getSaveFileName(
        // 参数同getOpenFileName
    )

    弹出文件保存框,返回用户指定的保存路径(QString类型)。

cpp 复制代码
QString str=QFileDialog::getOpenFileName(this,"选择一个文件","C:/");
qDebug()<<str<<endl;

1.7.3 输入对话框 QInputDialog

QInputDialog 是Qt预定义的对话框类,用来快速实现临时数据输入的场景(不用自己写输入界面,直接调用静态方法就能弹出输入框)。它的静态方法提供了多种输入类型的对话框,覆盖"小数、整数、选择条目"等常见输入场景。

  • parent:对话框的父窗口(决定显示位置、模态等);
  • title:对话框的标题栏文字(比如"输入整数");
  • label:对话框内的提示文字(比如"请输入年龄:");
  • items:仅getItem用,是可供选择的条目列表;
  • ok:判断用户是否确认输入:
  1. 双精度浮点型输入(输入小数)
cpp 复制代码
double getDouble(
    QWidget *parent,          // 父窗口
    const QString &title,     // 对话框标题
    const QString &label,     // 对话框内的提示标签(比如"请输入数值:")
    double value = 0,         // 输入框默认值(默认0)
    double min = -2147483647, // 输入最小值(默认极小值)
    double max = 2147483647,  // 输入最大值(默认极大值)
    int decimals = 1,         // 保留的小数位数(默认1位)
    bool *ok = nullptr,       // 输出参数:判断用户是否确认输入
    Qt::WindowFlags flags = Qt::WindowFlags() // 窗口标志
);

弹出输入框,接收用户输入的小数,返回输入的double值。

  1. 整型输入(输入整数)
cpp 复制代码
int getInt(
    QWidget *parent,
    const QString &title,
    const QString &label,
    int value = 0,            // 输入框默认值(默认0)
    int min = -2147483647,    // 输入最小值
    int max = 2147483647,     // 输入最大值
    int step = 1,             // 调整数值的步长(比如按上下箭头每次变1)
    bool *ok = nullptr,
    Qt::WindowFlags flags = Qt::WindowFlags()
);

弹出输入框,接收用户输入的整数,返回输入的int值。

  1. 选择条目型输入(从列表选内容)
cpp 复制代码
QString getItem(
    QWidget *parent,
    const QString &title,
    const QString &label,
    const QStringList &items, // 可供选择的条目列表(比如{"选项1","选项2"})
    int current = 0,          // 默认选中的条目索引(默认第1个)
    bool editable = true,     // 输入框是否可编辑(true=可以手动改内容)
    bool *ok = nullptr,
    Qt::WindowFlags flags = Qt::WindowFlags(),
    Qt::InputMethodHints inputMethodHints = Qt::ImhNone
);

弹出选择框,让用户从items列表选内容(也能手动编辑),返回选中/编辑后的QString值。

1.7.4 字体对话框 QFontDialog

getFont()QFontDialog 类的静态方法(无需手动创建 QFontDialog 对象),调用后会弹出系统风格的字体选择对话框,用户选择完成后返回对应的 QFont 对象,同时能判断用户是"确认"还是"取消"了选择。

cpp 复制代码
QFont QFontDialog::getFont(
    bool *ok,                  		 // 输出参数:判断用户是否确认选择
    const QFont &initial = QFont(),  // 初始字体(对话框默认显示的字体)
    QWidget *parent = nullptr,       // 父窗口(决定对话框的显示位置/模态)
    const QString &title = QString(),// 对话框标题(比如"选择字体")
    QFontDialog::FontDialogOptions options = FontDialogOptions() // 可选配置
);
cpp 复制代码
void MainWindow::fontdialog()
{
    bool ok;
    QFont font=QFontDialog::getFont(&ok);
    if(ok==true)//用户选择OK
    {
        qDebug()<<"选中字体"<<endl;
        qDebug()<<font.family()<<endl;
        qDebug()<<font.pointSize()<<endl;
        qDebug()<<font.bold()<<endl;
        qDebug()<<font.italic()<<endl;
    }
    else//用户选择cancel
    {
        qDebug()<<"初始字体"<<endl;
        qDebug()<<font.family()<<endl;
        qDebug()<<font.pointSize()<<endl;
        qDebug()<<font.bold()<<endl;
        qDebug()<<font.italic()<<endl;
    }
}

1.7.5 进度对话框 QProgressDialog

  • 作用:显示耗时任务的进度,支持用户取消任务。

  • 核心属性

    • range:进度范围(如0-100);
    • cancelButtonText:取消按钮文字;
    • minimumDuration:延迟显示时间(避免短任务闪框)。
  • 使用示例

    cpp 复制代码
    QProgressDialog progress("正在处理数据...", "取消", 0, 100, this);
    progress.setMinimumDuration(500); // 500ms后再显示
    progress.setWindowModality(Qt::WindowModal); // 模态(阻塞父窗口)
    
    for (int i = 0; i <= 100; ++i) {
        progress.setValue(i);
        QCoreApplication::processEvents(); // 刷新界面
    
        if (progress.wasCanceled()) { // 检测是否取消
            qDebug() << "任务被取消";
            break;
        }
        QThread::msleep(50); // 模拟耗时操作
    }

1.7.6 颜色对话框 QColorDialog

常用方法

方法原型 作用说明
QColorDialog(QWidget *parent = nullptr) 创建颜色对话框对象,同时指定父窗口(对话框会关联到父窗口,模态时阻塞父窗口)
QColorDialog(const QColor &initial, QWidget *parent = nullptr) 创建时设置默认选中的颜色initial)+ 父窗口(比如默认选中红色)
void setCurrentColor(const QColor &color) 设置对话框当前选中的颜色(打开对话框后默认显示该颜色)
QColor currentColor() const 获取对话框当前选中的颜色(用户选择后调用,拿到最终颜色)
QColor getColor(...)(静态方法) 直接打开模态颜色对话框,返回用户选择的颜色;无需手动创建对象(最常用)
void open(QObject *receiver, const char *member) 打开非模态颜色对话框 ,并绑定信号槽(用户选色后触发receivermember槽函数)
  1. 静态方法 getColor:直接调用
    QColorDialog::getColor(const QColor &initial = Qt::white, QWidget *parent = nullptr, const QString&title = QString(), QColorDialog::ColorDialogOptions options = ColorDialogOptions())
    打开模态对话框 (阻塞父窗口),返回用户选择的颜色;若用户点击"Cancel",返回的颜色是无效的(需判断有效性)。
  • initial:对话框打开时的默认颜色 (比如Qt::whiteQColor(255,0,0));
  • parent:对话框的父窗口对象(用于模态关联、窗口层级管理);
  • title:对话框的标题(比如"选择按钮背景色");
  • options:对话框的功能选项(比如QColorDialog::ShowAlphaChannel显示透明度通道)。
cpp 复制代码
QColor color=QColorDialog::getColor(QColor(0,0,0),this,"选择颜色");
this->setStyleSheet(QString(
      "QWidget { background-color: rgb(%1, %2, %3); }"
  ).arg(color.red()).arg(color.green()).arg(color.blue()));
  1. 实例化+open:先创建QColorDialog对象,再调用open()打开非模态对话框(不阻塞父窗口),通过信号槽获取用户选择的颜色。
cpp 复制代码
// 在主窗口构造函数中初始化颜色对话框
QColorDialog *colorDlg = new QColorDialog(Qt::red, this); // 默认颜色红色
colorDlg->setWindowTitle("非模态颜色选择");

// 绑定非模态对话框的"选色完成"信号到槽函数
connect(colorDlg, &QColorDialog::colorSelected, this, [=](const QColor &color){
    // 获取选中的颜色,设置文本框颜色
    if (color.isValid()) {
        ui->textEdit->setTextColor(color);
    }
});

// 点击按钮打开非模态对话框
connect(ui->btnOpenNonModal, &QPushButton::clicked, [=](){
    colorDlg->open(); // 非模态显示,不阻塞父窗口
});
相关推荐
代码匠心8 小时前
AI 自动编程:一句话设计高颜值博客
前端·ai·ai编程·claude
_AaronWong9 小时前
Electron 实现仿豆包划词取词功能:从 AI 生成到落地踩坑记
前端·javascript·vue.js
cxxcode9 小时前
I/O 多路复用:从浏览器到 Linux 内核
前端
用户54330814419410 小时前
AI 时代,前端逆向的门槛已经低到离谱 — 以 Upwork 为例
前端
JarvanMo10 小时前
Flutter 版本的 material_ui 已经上架 pub.dev 啦!快来抢先体验吧。
前端
恋猫de小郭10 小时前
AI 可以让 WIFI 实现监控室内人体位置和姿态,无需摄像头?
前端·人工智能·ai编程
哀木10 小时前
给自己整一个 claude code,解锁编程新姿势
前端
程序员鱼皮10 小时前
GitHub 关注突破 2w,我总结了 10 个涨星涨粉技巧!
前端·后端·github
UrbanJazzerati10 小时前
Vue3 父子组件通信完全指南
前端·面试
是一碗螺丝粉10 小时前
5分钟上手LangChain.js:用DeepSeek给你的App加上AI能力
前端·人工智能·langchain