【QT】常⽤控件详解(八) Qt窗⼝ 菜单栏 工具栏 状态栏 浮动窗口 五种内置对话框
文章目录
- 一、Qt窗⼝
- 二、菜单栏
- 1.1 创建菜单栏
- 1.2 在菜单栏中添加菜单
- 1.3 创建菜单项
- 1.4 在菜单项之间添加分割线
- 1.5 综合⽰例
- 三、⼯具栏
- 3.1 创建⼯具栏
- 3.2 设置停靠位置
- 3.3 设置浮动属性
- 3.4 设置浮动属性
- 3.5 综合例子
- 三、状态栏
- 3.1 状态栏的创建
- 3.2 在状态栏中显⽰实时消息
- 3.3 在状态栏中显⽰永久消息
- 3.3 在状态栏中创建进度条
- 四、浮动窗⼝
- 4.1 浮动窗⼝的创建
- 4.2 设置停靠的位置
- 4.3 设置浮动窗⼝只允许上下停靠
- 五、对话框
- 5.1 对话框介绍
- 5.2 对话框的分类
- 5.2.1 模态对话框
- 5.2.2 ⾮模态对话框
- 5.2.2 混合属性对话框
- 六、 Qt内置对话框
- 6.1 消息对话框QMessageBox
- 6.1.1 问题提⽰消息对话框
- 6.1.2 信息提⽰消息对话框
- 6.1.3 警告信息消息对话框
- 6.1.3 错误提⽰消息对话框
- 6.2 颜⾊对话框QColorDialog
- 6.2 ⽂件对话框QFileDialog
- 6.2.1 打开⽂件
- 6.2.2 保存⽂件
- 6.3 字体对话框QFontDialog
- 6.4 输⼊对话框QInputDialog
- 6.4.1 浮点型数据或者整型数据输⼊对话框
- 6.4.2 浮点型数据或者整型数据输⼊对话框
- 🚩总结
一、Qt窗⼝
Qt窗⼝是通过QMainWindow类来实现的。之前学的都是Widget的一些控件。
QMainWindow是一个为用户提供主窗口程序的类,继承自QWidget类,并且提供了一个预定义的布局。QMainWindow包含一个菜单栏(menu bar)、多个工具栏(tool bars)、多个浮动窗口(铆接部件)(dock widgets)、一个状态栏(status bar)和一个中心部件(central widget),它是许多应用程序的基础,如文本编辑器,图片编辑器等。如下图为QMainwindow中各组件所处的位置
这是典型的 GUI 应用主窗口布局(类似 Qt 的 QMainWindow
结构),各部分功能如下:
- Window Title(窗口标题栏)
- 作用:显示窗口名称(如软件名称),同时集成系统级交互(拖动窗口、最小化/最大化/关闭窗口,由操作系统提供)。
- Menu Bar(菜单栏)
- 作用:组织软件的核心功能,以 层级菜单 形式呈现(如“文件→打开”“编辑→复制”),是用户查找功能的核心入口。
- Tool Bar Area(工具栏区域)
- 作用:放置 高频功能的快捷按钮(如“保存”“撤销”图标),方便用户快速操作,通常可自由停靠、隐藏或移动。
- Dock Widget Area(停靠部件区)
- 作用:容纳 可浮动/停靠的辅助窗口(如属性面板、目录树、日志窗口),用户可拖动调整位置(甚至脱离主窗口成为独立窗口),灵活定制工作区布局。
- Central Widget(中心部件)
- 作用:软件的 核心工作区,承载主要交互内容(如文档编辑区、图像预览区、3D视图等),是用户操作的聚焦区域。
- Status Bar(状态栏)
- 作用:显示 实时状态信息(如操作提示、进度条、错误反馈、鼠标坐标等),向用户传递后台状态或辅助信息。
二、菜单栏
Qt中的菜单栏是通过QMenuBar这个类来实现的。一个主窗口最多只有一个菜单栏。位于主窗口顶部、主窗口标题栏下面。
菜单栏中包含菜单.菜单中包含菜单项.
1.1 创建菜单栏
⽅式⼀:菜单栏的创建可以借助于QMainWindow类提供的menuBar()函数来实现。
menubar()函数原型如下:
QMenuBar*menuBar()const
//方法一:menuBar()函数来实现
//创建菜单栏
QMenuBar* menubar = menuBar();
//将菜单栏放入窗口中
this->setMenuBar(menubar);// 方法二:在堆上动态创建;
// QMenuBar* menuBar = new QMenuBar(this);
// //将菜单栏放入窗口中
// this->setMenuBar(menuBar);
使⽤setMenuBar 把菜单栏放到窗⼝中.
1.2 在菜单栏中添加菜单
创建菜单,并通过QMenu提供的addMenu ()函数来添加菜单。
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QTextEdit>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();// 对应三个菜单项的槽函数void onOpen(); // 处理"open"操作void onClose(); // 处理"close"操作void onSave(); // 处理"save"操作void save();void load();
private:Ui::MainWindow *ui;QTextEdit* edit; // 文本编辑框// 可以在这里声明一个变量模拟"当前文件"状态bool isFileOpened = false; // 标记是否有文件打开
};
#endif // MAINWINDOW_H
//2. 创建菜单
QMenu* menu1 = new QMenu("文件");
QMenu* menu2 = new QMenu("编辑");
QMenu* menu3 = new QMenu("视图");
QMenu* menu4 = new QMenu("构建");
QMenu* menu5 = new QMenu("调试");//3. 添加菜单到菜单栏中
menubar->addMenu(menu1);
menubar->addMenu(menu2);
menubar->addMenu(menu3);
menubar->addMenu(menu4);
menubar->addMenu(menu5);
1.3 创建菜单项
在Qt中,并没有专⻔的菜单项类,可以通过QAction 类,抽象出公共的动作。如在菜单中添加菜单项
QAction可以给菜单栏使⽤,也可以给⼯具栏使⽤.
//4. 给菜单增加菜单项QAction* act1 = new QAction("open");QAction* act2 = new QAction("close");QAction* act3 = new QAction("save");menu1->addAction(act1);menu1->addSeparator(); ///在“open”和“close”中间添加分割线menu1->addAction(act2);menu1->addAction(act3);
1.4 在菜单项之间添加分割线
在菜单项之间可以添加分割线。分割线如下图所⽰,添加分割线是通过addSeparator() 函数来实现;
1.5 综合⽰例
//4. 给菜单增加菜单项
QAction* act1 = new QAction("open");
QAction* act2 = new QAction("close");
QAction* act3 = new QAction("save");
menu1->addAction(act1);
menu1->addSeparator(); ///在“open”和“close”中间添加分割线
menu1->addAction(act2);
menu1->addAction(act3);
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <string>
#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QMessageBox>
#include <QFileDialog>
#include <QString>
#include <fstream> // 支持std::ofstream
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 设置标题this->setWindowTitle("我的记事本");//方法一:menuBar()函数来实现//创建菜单栏QMenuBar* menubar = menuBar();//将菜单栏放入窗口中this->setMenuBar(menubar);// 方法二:在堆上动态创建;// QMenuBar* menuBar = new QMenuBar(this);// //将菜单栏放入窗口中// this->setMenuBar(menuBar);//2. 创建菜单QMenu* menu1 = new QMenu("文件");QMenu* menu2 = new QMenu("编辑");QMenu* menu3 = new QMenu("视图");QMenu* menu4 = new QMenu("构建");QMenu* menu5 = new QMenu("调试");//3. 添加菜单到菜单栏中menubar->addMenu(menu1);menubar->addMenu(menu2);menubar->addMenu(menu3);menubar->addMenu(menu4);menubar->addMenu(menu5);//4. 给菜单增加菜单项QAction* act1 = new QAction("open");QAction* act2 = new QAction("close");QAction* act3 = new QAction("save");QAction* act4 = new QAction("保存");QAction* act5 = new QAction("加载");menu1->addAction(act1);menu1->addSeparator(); ///在“open”和“close”中间添加分割线menu1->addAction(act2);menu1->addAction(act3);menu1->addAction(act4);menu1->addAction(act5);//给 action 添加信号槽, 上面的菜单项被点击后会产生一个 triggered 信号connect(act1, &QAction::triggered, this, &MainWindow::onOpen);connect(act2, &QAction::triggered, this, &MainWindow::onClose);connect(act3, &QAction::triggered, this, &MainWindow::onSave);connect(act4, &QAction::triggered, this, &MainWindow::save);connect(act5, &QAction::triggered, this, &MainWindow::load);// 创建中央控件edit = new QTextEdit(this);this->setCentralWidget(edit);edit->setPlaceholderText("此处编写⽂本内容...");
}// 实现槽函数:处理"open"
void MainWindow::onOpen()
{if (isFileOpened) {QMessageBox::information(this, "提示", "已经打开了一个文件哦~");} else {isFileOpened = true;QMessageBox::information(this, "操作成功", "文件已打开!\n可以开始编辑啦~");// 实际应用中这里会添加打开文件对话框的代码}
}// 实现槽函数:处理"close"
void MainWindow::onClose()
{if (!isFileOpened) {QMessageBox::warning(this, "提示", "没有打开的文件可关闭哦~");} else {isFileOpened = false;QMessageBox::information(this, "操作成功", "文件已关闭!");// 实际应用中这里会添加保存提示、清理资源的代码}
}// 实现槽函数:处理"save"
void MainWindow::onSave()
{if (!isFileOpened) {QMessageBox::warning(this, "提示", "先打开文件才能保存哦~");} else {QMessageBox::information(this, "操作成功", "文件已保存!\n数据安全啦~");// 实际应用中这里会添加保存文件对话框、写入数据的代码}
}void MainWindow::save()
{//弹出对话框,选择写入文件的路径QFileDialog* dialog = new QFileDialog(this);QString fileName = dialog->getSaveFileName(this, "保存文件", "D:/CSDN/my-qt/QtMainWindow/Qt_MianWindow_1");qDebug() << "fileName: " << fileName;//写入文件std::ofstream file(fileName.toStdString().c_str());if (!file.is_open()) {qDebug() << "文件保存失败!无法打开文件";return;}const QString& text = edit->toPlainText(); // 现在edit是成员变量,可访问file << text.toStdString();file.close(); // 显式关闭文件(可选,析构时会自动关闭)qDebug() << "文件保存成功!";
}void MainWindow::load()
{//弹出对话框,选择写入文件的路径QFileDialog* dialog = new QFileDialog(this);QString fileName = dialog->getOpenFileName(this, "加载⽂件", "D:/CSDN/my-qt/QtMainWindow/Qt_MianWindow_1");qDebug() << "fileName: " << fileName;//写入文件std::ifstream file(fileName.toStdString().c_str());if(!file.is_open()){qDebug() << "文件加载失败!";return;}std::string content;std::string line;while(std::getline(file, line)){content += line;content += "\n";}file.close();//显示到界面上QString text = QString::fromStdString(content);edit->setPlainText(text);
}MainWindow::~MainWindow()
{delete ui;
}
三、⼯具栏
⼯具栏是应⽤程序中集成各种功能实现快捷键使⽤的⼀个区域。可以有多个,也可以没有,它并不是应⽤程序中必须存在的组件。它是⼀个可移动的组件,它的元素可以是各种窗⼝组件,它的元素通常以图标按钮的⽅式存在。如下图为⼯具栏的⽰意图:
3.1 创建⼯具栏
调⽤QMainWindow类的addToolBar()函数来创建⼯具栏,每增加⼀个⼯具栏都需要调⽤⼀次该函数。
如添加两个⼯具栏:
3.2 设置停靠位置
⼯具栏停靠位置的设置有两种⽅式。⼀种是在创建⼯具栏的同时指定停靠的位置,另⼀种是通过QToolBar类提供的setAllowedAreas()函数来设置。
⽅式⼀:创建⼯具栏的同时指定其停靠的位置。
在创建⼯具栏的同时,也可以设置⼯具栏的位置,其默认位置是在窗⼝的最上⾯;如上述代码,默认在最上⾯显⽰。⼯具栏允许停靠的区域由QToolBar类提供的allowAreas()函数决定,其中可以设置的位置包括:
- Qt::LeftToolBarArea停靠在左侧
- Qt::RightToolBarArea停靠在右侧
- Qt::TopToolBarArea停靠在顶部
- Qt:BottomToolBarArea停靠在底部
- Qt:AllToolBarAreas
⽅式⼆:使⽤QToolBar类提供的setAllowedAreas()函数设置停靠位置。如下⽰例:
说明:
在创建⼯具栏的同时指定其停靠的位置,指的是程序运⾏时⼯具栏默认所在的位置;⽽使⽤
setAllowedAreas()函数设置停靠位置,指的是⼯具栏允许其所能停靠的位置
3.3 设置浮动属性
⼯具栏的浮动属性可以通过QToolBar类提供的setFloatable()函数来设置。setFloatable()函数原
型为:
void setFloatable (bool floatable)
参数:
true:浮动
false:不浮动
⽰例:
3.4 设置浮动属性
设置⼯具栏的移动属性可以通过QToolBar类提供的setMovable()函数来设置。setMovable()函数
原型为:
void setMovable(bool movable)
参数:
true:移动
false:不移动
说明:若设置⼯具栏为不移动状态,则设置其停靠位置的操作就不会⽣效,所以设置⼯具栏
的移动属性类似于总开关的效果。
3.5 综合例子
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QToolBar>
#include <QPushButton>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);QToolBar* toolBar = new QToolBar(this);//设置工具栏的位置:默认是在窗口上面,此处设置为在左侧addToolBar(Qt::LeftToolBarArea, toolBar);//设置工具栏的停靠位置, 设置工具栏只允许在左右停靠toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);//设置工具栏的浮动属性toolBar->setFloatable(true);//设置工具栏的移动总开关toolBar->setMovable(true);//设置工具栏的内容QAction* openAction = new QAction("open",this);QAction* newAction = new QAction("new", this);toolBar->addAction(openAction);toolBar->addSeparator();toolBar->addAction(newAction);//在工具栏中也可以添加控件QPushButton* btn = new QPushButton("保存", this);toolBar->addWidget(btn);
}
可拖拉移动
三、状态栏
状态栏是应⽤程序中输出简要信息的区域。⼀般位于主窗⼝的最底部,⼀个窗⼝中最多只能有⼀个状
态栏。在Qt中,状态栏是通过QStatusBar类来实现的。 在状态栏中可以显⽰的消息类型有:
- 实时消息:如当前程序状态
- 永久消息:如程序版本号,机构名称
- 进度消息:如进度条提示,百分百提示
3.1 状态栏的创建
状态栏的创建是通过QMainWindow类提供的 statusBar()函数来创建;⽰例如下:
3.2 在状态栏中显⽰实时消息
在状态栏中显⽰实时消息是通过showMessage()函数来实现,⽰例如下
3.3 在状态栏中显⽰永久消息
在状态栏中可以显⽰永久消息,此处的永久消息是通过标签来显⽰的;⽰例如下:
显⽰效果如下:
调整显⽰消息的位置
显⽰效果如下:
3.3 在状态栏中创建进度条
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QProgressBar> // 进度条头文件
#include <QTimer> // 定时器头文件
#include <QLabel>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECT // 必须添加,支持信号槽机制public:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void updateProgress(); // 进度条更新槽函数private:Ui::MainWindow *ui;QLabel *label;QProgressBar* progressBar; // 进度条对象QTimer* timer; // 定时器(驱动进度变化)int progressValue = 0; // 当前进度值(初始为0)
};#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QString>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this); // 初始化UI(必调,即使.ui是空的)// ========== 状态栏 + 进度条初始化 ==========QStatusBar* stbar = statusBar(); // 获取默认状态栏// 1. 创建进度条progressBar = new QProgressBar(this);progressBar->setRange(0, 100); // 进度范围:0~100progressBar->setTextVisible(true); // 显示百分比文字(如“50%”)stbar->addPermanentWidget(progressBar); // 把进度条加入状态栏//创建标签label = new QLabel("当前加载文件进度:",this);//将标签放入状态栏中stbar->addWidget(label) ;// 2. 定时器驱动进度变化timer = new QTimer(this);connect(timer, &QTimer::timeout, this, &MainWindow::updateProgress);timer->start(100); // 每 100ms 触发一次更新(每秒跳10次)
}void MainWindow::updateProgress()
{progressValue++;if (progressValue > 100) {progressValue = 0; // 超过100%后重置为0,循环跳动}progressBar->setValue(progressValue); // 更新进度条显示label->setText(QString("当前加载文件进度:%1%").arg(progressValue));
}MainWindow::~MainWindow()
{delete ui;
}
四、浮动窗⼝
在Qt中,浮动窗⼝也称之为铆接部件。浮动窗⼝是通过QDockWidget类来实现浮动的功能。浮动窗
⼝⼀般是位于核⼼部件的周围,可以有多个。
4.1 浮动窗⼝的创建
浮动窗⼝的创建是通过QDockWidget类提供的构造⽅法QDockWidget()函数动态创建的;
⽰例如下:
4.2 设置停靠的位置
浮动窗⼝是位于中⼼部件的周围。可以通过QDockWidget类中提供setAllowedAreas()函数设置其
允许停靠的位置。其中可以设置允许停靠的位置有:
- Qt::LeftDockWidgetArea停靠在左侧
- Qt::RightDockWidgetArea停靠在右侧
- Qt::TopDockWidgetArea停靠在顶部
- Qt:BottomDockWidgetArea停靠在底部
- Qt::AllDockWidgetAreas以上四个位置都可停靠
4.3 设置浮动窗⼝只允许上下停靠
//设置浮动窗口的停靠区域,只允许上下停靠
dockwidget->setAllowedAreas(Qt::TopDockwidgetArea / Qt::BottomDockWidgetArea);
五、对话框
5.1 对话框介绍
对话框是GUI程序中不可或缺的组成部分。⼀些不适合在主窗⼝实现的功能组件可以设置在对话框中。对话框通常是⼀个顶层窗⼝,出现在程序最上层,⽤于实现短期任务或者简洁的⽤⼾交互。Qt常⽤的内置对话框有:QFiledialog(⽂件对话框)、QColorDialog(颜⾊对话框)、QFontDialog(字体对话框)、QInputDialog(输⼊对话框)和QMessageBox(消息框)。
- 基础问题:按下按钮弹出弹窗,关闭后再次点击,弹出的弹窗和第一次是同一个对象吗?
-
延伸问题:多次点击按钮创建对话框对象,会导致内存泄漏,如何解决?
-
对象唯一性:每次点击按钮,都会创建新的
QDialog
对象(非同一对象),默认关闭弹窗时仅隐藏(setVisible(false)
),不销毁对象。 -
内存泄漏原因:若不主动释放,多次创建的对话框对象会持续占用内存,导致泄漏。
方案 1:利用 Qt::WA_DeleteOnClose
属性(推荐,最简)
- 核心逻辑:给对话框设置「关闭时自动销毁」属性,弹窗关闭后 Qt 自动释放其内存。
- 代码示例:
#include <QMainWindow> #include <QPushButton> #include <QDialog> #include <QLabel>class MainWindow : public QMainWindow {Q_OBJECT public:MainWindow(QWidget *parent = nullptr) {// 1. 创建按钮QPushButton *btn = new QPushButton("弹对话框", this);setCentralWidget(btn);// 2. 按钮点击事件:创建对话框connect(btn, &QPushButton::clicked, this, [=]() {QDialog *dialog = new QDialog(this); // 每次点击新建对象dialog->setWindowTitle("自动销毁弹窗");new QLabel("关闭我会自动释放内存", dialog); // 子控件随对话框销毁// 关键:设置“关闭时自动删除”属性dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->exec(); // 模态显示(非模态用 show(),效果一致)});} };
方案 2:连接 finished
信号手动释放(灵活场景)
- 核心逻辑:对话框关闭后会触发
finished
信号,关联该信号到deleteLater()
,安全释放内存(避免信号槽执行时对象被销毁的冲突)。 - 代码示例:
connect(btn, &QPushButton::clicked, this, [=]() {QDialog *dialog = new QDialog(this);dialog->setWindowTitle("手动释放弹窗");// 关键:弹窗关闭后,触发 deleteLater() 释放内存connect(dialog, &QDialog::finished, dialog, &QObject::deleteLater);dialog->show(); // 非模态场景常用(exec() 也适用) });
方案 | 优点 | 适用场景 |
---|---|---|
Qt::WA_DeleteOnClose | 代码极简,无需手动管理 | 大多数简单弹窗(无额外逻辑) |
finished + deleteLater | 可插入关闭后自定义逻辑 | 需统计关闭原因、清理数据等 |
5.2 对话框的分类
对话框分为模态对话框和⾮模态对话框。
5.2.1 模态对话框
模态对话框指的是:显⽰后⽆法与⽗窗⼝进⾏交互,是⼀种阻塞式的对话框。使⽤QDialog::exec()函
数调⽤。
模态对话框适⽤于必须依赖⽤⼾选择的场合,⽐如消息显⽰,⽂件选择,打印设置等。
⽰例:
#include "dialog.h"
#include "ui_dialog.h"
#include <QPushButton>Dialog::Dialog(QWidget *parent): QDialog(parent), ui(new Ui::Dialog)
{ui->setupUi(this);// 1. 创建触发按钮QPushButton *btn = new QPushButton("点击打开模态对话框", this);resize(400, 300); // 调整主窗口大小// 2. 按钮点击 → 弹出模态对话框connect(btn, &QPushButton::clicked, this, [=]() {Dialog dialog(this); // 创建自定义对话框(父窗口设为当前主窗口)dialog.exec(); // 模态显示:阻塞主窗口,直到对话框关闭});
}
点击主窗口的按钮后,弹出对话框,主窗口会被 “锁住”(按钮无法点击、无法拖动主窗口等)。
必须关闭对话框(点击右上角 ×),才能重新操作主窗口
5.2.2 ⾮模态对话框
⾮模态对话框显⽰后独⽴存在,可以同时与⽗窗⼝进⾏交互,是⼀种⾮阻塞式对话框,使⽤
QDialog::show()函数调⽤。
⾮模态对话框⼀般在堆上创建,这是因为如果创建在栈上时,弹出的⾮模态对话框就会⼀闪⽽过。同
时还需要设置Qt:WA_DeleteOnClose属性,⽬的是:当创建多个⾮模态对话框时(如打开了多个⾮
模态窗⼝),为了避免内存泄漏要设置此属性。
⾮模态对话框适⽤于特殊功能设置的场合,⽐如查找操作,属性设置等
dialog.h
非模态显示,不阻塞主线程,允许同时操作触发按钮和其他界面。
#include "dialog.h"
#include "ui_dialog.h"
#include <QPushButton>Dialog::Dialog(QWidget *parent): QDialog(parent), ui(new Ui::Dialog)
{ui->setupUi(this);setWindowTitle("查找(非模态)");resize(300, 150);// 1. 创建控件edit = new QLineEdit(this);edit->setPlaceholderText("输入要查找的内容...");edit->move(20, 20);btnFind = new QPushButton("查找", this);btnFind->move(20, 60);// 2. 连接信号槽:点击按钮触发查找逻辑connect(btnFind, &QPushButton::clicked, this, &Dialog::onFindClicked);
}void Dialog::onFindClicked()
{QString text = edit->text().trimmed();if (!text.isEmpty()) {qDebug() << "[查找] 内容:" << text;// 扩展:可向主窗口发送信号,执行真实查找逻辑(如遍历文本)} else {qDebug() << "[提示] 请输入查找内容!";}
}
Dialog::~Dialog()
{delete ui;
}
main.cpp
#include "dialog.h"
#include <QApplication>
#include <QPushButton> // 用于创建触发按钮int main(int argc, char *argv[])
{QApplication app(argc, argv);// 步骤1:创建一个“触发按钮” QPushButton triggerBtn("点击我,弹出非模态对话框", nullptr);triggerBtn.resize(300, 60); // 按钮大小triggerBtn.show(); // 显示按钮// 步骤2:按钮点击 → 弹出非模态对话框 QObject::connect(&triggerBtn, &QPushButton::clicked, [&]() {// 关键1:堆上创建 Dialog(避免栈变量“一闪而过”)Dialog* dialog = new Dialog(&triggerBtn);// 关键2:设置“关闭时自动销毁”,防止内存泄漏dialog->setAttribute(Qt::WA_DeleteOnClose);// 关键3:非模态显示(调用 show(),不阻塞当前线程)dialog->show();});return app.exec();
}
这样就可以一边查找代码,一边编写代码,不一定要关了查找框才能写代码
5.2.2 混合属性对话框
混合属性对话框同时具有模态对话框和⾮模态对话框的属性,对话框的⽣成和销毁具有⾮模态对话框
属性,功能上具有模态对话框的属性。
使⽤QDialog::setModal()函数可以创建混合特性的对话框。通常,创建对话框时需要指定对话框的
⽗组件。
⽰例:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 1:手动创建“actionnew”(模拟 UI 设计器的动作)QAction* actionNew = new QAction("新建混合对话框", this);actionNew->setObjectName("actionnew");// 2:将动作添加到菜单栏(模拟 UI 布局)QMenu* fileMenu = menuBar()->addMenu("文件");fileMenu->addAction(actionNew);// 3:连接动作触发信号,创建混合对话框connect(actionNew, &QAction::triggered, this, [=]() {QDialog *dialog = new QDialog(this); // 父窗口设为当前主窗口dialog->setWindowTitle("混合属性对话框");// 混合特性设置:dialog->setAttribute(Qt::WA_DeleteOnClose); // 关闭自动销毁(非模态销毁特性)dialog->setModal(true); // 阻塞父窗口(模态功能特性)dialog->resize(200, 100); // 设置对话框大小// 非模态方式显示(但因 setModal(true),实际表现为“功能模态”)dialog->show();});
}
六、 Qt内置对话框
Qt提供了多种可复⽤的对话框类型,即Qt标准对话框。Qt标准对话框全部继承于QDialog类。常⽤
标准对话框如下:
6.1 消息对话框QMessageBox
消息对话框是应⽤程序中最常⽤的界⾯元素。消息对话框主要⽤于为⽤⼾提⽰重要信息,强制⽤⼾进
⾏选择操作。
QMessageBox类中定义了静态成员函数,可以直接调⽤创建不同⻛格的消息对话框,其中包括:
类型 | 用途 |
---|---|
Question | 用于正常操作过程中的提问 |
Information | 用于报告正常运行信息 |
Warning | 用于报告非关键错误 |
Critical | 用于报告严重错误 |
其对应的函数原型如下: | |
![]() |
6.1.1 问题提⽰消息对话框
实现效果如下
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QPushButton>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);resize(800, 600);QPushButton* btn = new QPushButton("消息对话框", this);QMessageBox* msg = new QMessageBox(this);msg->setWindowTitle("Warning Message");//设置消息对话框的框体msg->setText("Error Message!");//设置消息对话框的内容msg->setIcon(QMessageBox::Question); //设置消息对话框类型msg->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); //在消息对话框上设置按钮connect(btn, &QPushButton::clicked, [=](){msg->show();});
}
其中可以设置的按钮的类型如下:
更改消息对话框中的按钮类型:
6.1.2 信息提⽰消息对话框
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QPushButton>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);resize(800, 600);QPushButton* btn = new QPushButton("消息对话框", this);QMessageBox* msg = new QMessageBox(this);msg->setWindowTitle("Warning Message");//设置消息对话框的框体msg->setText("Error Message!");//设置消息对话框的内容msg->setIcon(QMessageBox::Information); //设置消息对话框类型msg->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); //在消息对话框上设置按钮connect(btn, &QPushButton::clicked, [=](){msg->show();});
}
6.1.3 警告信息消息对话框
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QPushButton>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);resize(800, 600);QPushButton* btn = new QPushButton("消息对话框", this);QMessageBox* msg = new QMessageBox(this);msg->setWindowTitle("Warning Message");//设置消息对话框的框体msg->setText("Error Message!");//设置消息对话框的内容msg->setIcon(QMessageBox::Warning); //设置消息对话框类型msg->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); //在消息对话框上设置按钮connect(btn, &QPushButton::clicked, [=](){msg->show();});
}
6.1.3 错误提⽰消息对话框
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QPushButton>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);resize(800, 600);QPushButton* btn = new QPushButton("消息对话框", this);QMessageBox* msg = new QMessageBox(this);msg->setWindowTitle("Warning Message");//设置消息对话框的框体msg->setText("Error Message!");//设置消息对话框的内容msg->setIcon(QMessageBox::Critical); //设置消息对话框类型msg->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); //在消息对话框上设置按钮connect(btn, &QPushButton::clicked, [=](){msg->show();});
}
6.2 颜⾊对话框QColorDialog
常⽤⽅法介绍:
方法签名 | 功能说明 | 参数说明 |
---|---|---|
构造函数QColorDialog(QWidget* parent = nullptr) | 创建颜色对话框对象,同时指定父对象(默认无初始颜色) | parent :父窗口指针,用于管理对象生命周期 |
构造函数QColorDialog(const QColor &initial, QWidget *parent = nullptr) | 创建颜色对话框对象,同时指定初始颜色和父对象 | initial :初始颜色(QColor 对象);parent :父窗口指针 |
成员方法void setCurrentColor(const QColor &color) | 动态设置对话框的当前选中颜色(修改默认值) | color :要设置的颜色(QColor 对象) |
成员方法QColor currentColor() const | 获取对话框的当前选中颜色 | 无参数 |
静态方法static QColor getColor(const QColor &initial = Qt::white, QWidget *parent = nullptr, const QString &title = QString(), QColorDialog::ColorDialogOptions options = ColorDialogOptions()) | 直接打开阻塞式颜色对话框,返回用户选择的颜色(常用快捷方式) | initial :默认颜色(默认 Qt::white );parent :父窗口指针;title :对话框标题;options :配置选项(如是否显示Alpha通道) |
成员方法void open(QObject* receiver, const char* member) | 非阻塞打开对话框,用户确认后,自动触发 receiver 的 member 槽函数 | receiver :接收信号的对象;member :槽函数名(需符合 void onColorSelected(const QColor &) 签名,用 SLOT 语法) |
关键补充:
getColor
返回值:若用户取消选择,返回的QColor
可通过color.isValid()
判断是否有效。open
信号关联:需配合槽函数使用,例如:
槽函数定义:colorDialog->open(this, SLOT(onColorSelected(QColor)));
void MainWindow::onColorSelected(const QColor &color) {qDebug() << "选中颜色:" << color; }
ColorDialogOptions
:可配置特殊行为(如QColorDialog::ShowAlphaChannel
显示透明度滑块)。
颜⾊对话框的功能是允许⽤⼾选择颜⾊。继承⾃QDialog类。颜⾊对话框如下图⽰:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QColorDialog>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);resize(800, 600);QPushButton* btn = new QPushButton("颜色对话框", this);//创建颜色对话框QColorDialog* cdlg = new QColorDialog(this);connect(btn, &QPushButton::clicked, [=](){//打开颜色对话框,并设置默认颜色为红色QColor color = cdlg->getColor(QColor(255, 0,0));qDebug() << "r = " << color.red();qDebug() << "g = " << color.green();qDebug() << "b = " << color.blue();});connect(btn, &QPushButton::clicked, [=](){//打开颜色对话框,并设置默认颜色为红色//设置颜色对话框中的颜色cdlg->setCurrentColor(QColor( 200,100,190) );cdlg->open( );});}
6.2 ⽂件对话框QFileDialog
⽂件对话框⽤于应⽤程序中需要打开⼀个外部⽂件或需要将当前内容存储到指定的外部⽂件。
常⽤⽅法介绍:
方法签名 | 功能说明 | 参数说明 |
---|---|---|
QString getOpenFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = QFileDialog::Options()) | 打开单个文件,返回选中文件的路径(QString ) | parent :父窗口指针(控制对话框父子关系);caption :对话框标题(如 “选择文件”);dir :默认打开的目录(如 "C:/" );filter :文件过滤器(如 "文本文件 (*.txt);;图片 (*.png *.jpg)" ,多类型用 ;; 分隔);selectedFilter :输出参数,返回用户实际选择的过滤器(通常传 nullptr );options :对话框行为配置(如 QFileDialog::DontShowHiddenFiles 隐藏系统文件) |
QStringList getOpenFileNames(...) (参数与 getOpenFileName 完全一致) | 打开多个文件,返回选中文件的路径列表(QStringList ) | 同上述参数 |
QString getSaveFileName(...) (参数与 getOpenFileName 完全一致) | 保存文件,返回目标文件的路径(QString ) | 同上述参数 |
参数说明:
参数1:parent ⽗亲
参数2:caption 对话框标题
参数3:dir 默认打开的路径
参数4: filter 文件过滤器
关键补充:
- 过滤器语法:多类型过滤用
;;
分隔,例如:"Text Files (*.txt);;Images (*.png *.jpg);;All Files (*.*)"
options
常用值:QFileDialog::ShowHiddenFiles
:显示隐藏文件;QFileDialog::DontResolveSymlinks
:不解析符号链接。
- 返回值判断:若用户取消操作,
getOpenFileName
/getSaveFileName
返回空字符串,getOpenFileNames
返回空列表,需做判空处理。
6.2.1 打开⽂件
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QFileDialog>
#include <QDebug>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);resize(800, 600);QPushButton* btn = new QPushButton("文件", this);QFileDialog* fdlg = new QFileDialog(this);connect(btn, &QPushButton::clicked, [=](){QString str = fdlg->getOpenFileName(this, //父指针"文件", //文件对话框标题"D:/CSDN/my-qt/QtMainWindow/Qt_QFileDialog_1","*.cpp");});
}
只把.cpp
文件过滤处理啊
6.2.2 保存⽂件
connect(btn, &QPushButton::clicked, [=](){QString str = fdlg->getSaveFileName(this, //父指针"文件", //文件对话框标题"D:/CSDN/my-qt/QtMainWindow/Qt_QFileDialog_1","*.cpp");
});
6.3 字体对话框QFontDialog
Qt 中提供了预定义的字体对话框类QFontDialog,⽤于提供选择字体的对话框部件。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QFontDialog>
#include <QDebug>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);resize(800, 600);QPushButton* btn = new QPushButton("字体",this);connect(btn, &QPushButton::clicked, [=](){//使用QFontDialog 类的静态方法getFont ,打开字体对话框并设置默认格式bool flag; //由于getFont方法第一个参数是bool类型,所以有此定义QFont font = QFontDialog::getFont(&flag, QFont("宋体",36));//将 char* 转换为 QString 的方法: .toUtf8().data()qDebug() << "字体:"<< font.family().toUtf8().data();//获取字号qDebug() << "字号:"<< font.pointSize();//获取字体是否加粗qDebug() << "是否加粗:" << font.bold();//是否斜体qDebug() << "是否倾斜: "<< font.italic();});
}
6.4 输⼊对话框QInputDialog
Qt 中提供了预定义的输⼊对话框类:QInputDialog,⽤于进⾏临时数据输⼊的场合。
常⽤⽅法介绍:
方法签名 | 功能说明 | 核心参数说明 |
---|---|---|
double getDouble(QWidget* parent, const QString& title, const QString& label, double value = 0, double min = -2147483647, double max = 2147483647, int decimals = 1, bool* ok = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()) | 弹出双精度浮点型输入对话框,返回用户输入的数值(或默认值) | parent :父窗口指针;title :对话框标题;label :输入提示文本(如 “请输入体重”);value :默认数值;min/max :输入数值的最小/最大值;decimals :保留小数位数(默认1位);ok :输出参数,true 表示用户确认输入,false 表示取消 |
int getInt(QWidget *parent, const QString &title, const QString &label, int value = 0, int min = -2147483647, int max = 2147483647, int step = 1, bool* ok = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()) | 弹出整型输入对话框,返回用户输入的整数(或默认值) | 基础参数(parent /title /label /value /min /max /ok )同 getDouble ;step :数值调节步长(点击上下箭头时增减的幅度,默认1) |
QString getItem(QWidget* parent, const QString& title, const QString &label, const QStringList &items, int current = 0, bool editable = true, bool *ok = nullptr, Qt::WindowFlags flags = Qt::WindowFlags(), Qt::InputMethodHints inputMethodHints = Qt::ImhNone) | 弹出条目选择对话框,返回用户选中(或编辑)的文本 | 基础参数(parent /title /label /ok )同上述方法;items :供选择的条目列表(如 QStringList() << "苹果" << "香蕉" );current :默认选中的条目索引(从0开始);editable :是否允许编辑条目文本(默认 true ,可直接输入新内容) |
补充说明:
ok
参数用法:需提前定义bool
变量,判断用户操作结果,例:bool isConfirmed; int num = QInputDialog::getInt(this, "输入", "请输入数量", 10, 1, 100, 1, &isConfirmed); if (isConfirmed) { /* 处理用户输入的 num */ }
- 范围限制:
min
和max
约束输入值,用户无法输入超出范围的内容(对话框会自动拦截); editable
作用:getItem
中设为false
时,用户只能从items
中选择,无法手动输入。
6.4.1 浮点型数据或者整型数据输⼊对话框
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QInputDialog>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);resize(800, 600);QPushButton* btn = new QPushButton("输入框", this);QInputDialog* idlg = new QInputDialog(this);connect(btn, &QPushButton::clicked, [=](){double d = idlg->getDouble(this, "输入框", "浮点型");qDebug() << "d= " <<d;});}
整型数据输⼊对话框
connect(btn, &QPushButton::clicked, [=](){int i = idlg->getInt(this, "输入框", "Int");qDebug() << "i= " << i;
});
6.4.2 浮点型数据或者整型数据输⼊对话框
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QInputDialog>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);resize(800, 600);QPushButton* btn = new QPushButton("输入框", this);QInputDialog* idlg = new QInputDialog(this);connect(btn, &QPushButton::clicked, [=](){QStringList items;items << tr("Spring") << tr("Summer") << tr("Fall") << tr("Winter");QString item = idlg->getItem(this, "输入框", "Item", items);qDebug() << "item: "<< item.toUtf8().data();});
}