目录
对话框
1. 对话框的基本概念
2. 对话框的内存释放问题
3. 自定义对话框界面
3.1 使用纯代码的方式定义
3.2 使用图形化的方式定义
4. 对话框的分类
4.1 模态对话框
4.2 非模态对话框
4.3 混合属性对话框
5. Qt 内置对话框
5.1 消息对话框 QMessageBox
示例1:问题提示消息对话框
示例2:信息提示消息对话框
编辑
示例3:警告信息消息对话框
示例4:错误提示消息对话框
5.2 颜色对话框 QColorDialog
5.3 文件对话框 QFileDialog
5.4 字体对话框 QFontDialog
5.5 输入对话框 QInputDialog
对话框
1. 对话框的基本概念
对话框是 GUI 程序中不可或缺的组成部分。一些不适合在主窗口实现的功能组件可以设置在对话框中。对话框通常是一个顶层窗口,出现在程序最上层,用于实现短期任务或者简洁的用户交互。
Qt常用的内置对话框有:
- QFiledialog(文件对话框)
- QColorDialog(颜色对话框)
- QFontDialog (字体对话框)
- QInputDialog (输入对话框)
- QMessageBox(消息框)
Qt 中使用 QDialog 类表示对话框,针对一个已有的项目,也可以创建一些类,继承自 QDialog 实现咋们自定义的对话框。
实际开发中,更多的情况,往往不是直接在创建项目的时候继承自 QDialog,而是在代码中,创建额外的类继承自 QDialog。主窗口一般不会作为一个对话框,主窗口可以再产生出一些其他的对话框。
2. 对话框的内存释放问题
代码示例:在主窗口中,通过点击按钮,弹出一个新的对话框
1)在界面上创捷一个按钮
2)给 QPushButton 添加 slot 函数
- QDialog 其实也是 QWidget 的子类,QWidget 的各种属性方法,QDialog 也能使用。
void MainWindow::on_pushButton_clicked()
{
QDialog* dialog = new QDialog(this);
// 设置尺寸
dialog->resize(400, 300);
// 设置标题
dialog->setWindowTitle("对话框的标题");
// 通过 show 方法显示对话框
dialog->show();
}
3)执行程序,观察效果
注意:
- 不同于界面上的其他控件,此处 QDialog 每次按下按钮,都会创建一个新的 QDialog 对象,并进行显示,即每次点击都会创建新的对话框对象!
- 一个程序运行过程中,可以无数次点击这个按钮你,进一步的就产生出了无数个这样的对象,就会造成内存泄漏。
- 虽然我们将父元素设为了 this,QMainWindow 被销毁的时候,QDialog是会随之销毁,但是也架不住 QDialog 会在 QMainWindow 之前就存在很多个。如果你的这一对象占用内存很多,或者你的机器本身剩余的内存很少(嵌入式系统),也会出现内存泄漏。
4)释放内存
- 如果我们将 delete 放在代码最后面,对话框就会一闪而过,很显然,这不是我们想要的结果。
- 正确的做法,应该是让用户点击 对话框 关闭按钮的时候,再来触发这里的 delete 操作~
- 只要给 dialog 设置以下属性 ,就会在关闭的时候自动进行 delete.
dialog->setAttribute(Qt::WA_DeleteOnClose);
3. 自定义对话框界面
要想自定义对话框,就需要继承自 QDialog 创建类~
3.1 使用纯代码的方式定义
1)在界面上创建一个按钮
2)手动创建出一个新的类
- 文件 -> 新建 -> C++ -> C++ Class
创建成功后,项目中会多出来两个文件:
3)在 mainwindow.cpp 中编写 按钮 的 slot 函数
void MainWindow::on_pushButton_clicked()
{
Dialog* dialog = new Dialog(this);
dialog->resize(400, 300);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->show();
}
4)在 dialog.cpp 中编写如下代码
Dialog::Dialog(QWidget* parent) : QDialog(parent)
{
// 创建出一些控件,加入到 DiaLog 中(以 Dialog 作为父窗口)
QVBoxLayout* layout = new QVBoxLayout();
this->setLayout(layout);
QLabel* label = new QLabel("这是一个对话框", this);
QPushButton* button = new QPushButton("按钮", this);
layout->addWidget(label);
layout->addWidget(button);
connect(button, &QPushButton::clicked, this, &Dialog::handle);
}
void Dialog::handle()
{
this->close();
}
5)执行程序
3.2 使用图形化的方式定义
1)在界面上创建一个按钮
2) 新建一个 Qt 设计师界面类
新建成功后,项目中会出现以下文件:
3)在对话框的 ui 文件 中新建一个 按钮 和一个 标签
4)编写 mainwindow.ui 文件中 按钮 的槽函数
void MainWindow::on_pushButton_clicked()
{
// 弹出一个自定义的对话框
Dialog* dialog = new Dialog(this);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->show();
}
5)编写 dialog.ui 文件中 按钮 的槽函数,使其点击按钮能够关闭对话框
void Dialog::on_pushButton_clicked()
{
this->close();
}
6)执行程序,观察效果
4. 对话框的分类
对话框分为 模态对话框 和 非模态对话框。
4.1 模态对话框
模态对话框指的是:弹出对话框后,此时用户无法操作父窗口(显示后无法与父窗口进行交互),必须完成对话框内部出现的操作,关闭对话框之后才能继续后续操作,是一种阻塞式的对话框。用于特别关键的场合,用户必须要做出决策。
使用 QDialog::exec() 函数 调用。
模态对话框适用于必须依赖用户选择的场合,比如消息显示,文件选择,打印设置等。
示例:
1、新建 Qt 项母,在 ui 文件中的菜单栏中设置两个菜单:"文件" 和 "编辑",在 菜单 "文件" 下新建菜单项:"创建" 并将菜单项 "新建" 置于工具栏中 ; 如下图示:
2、在 mainwindow.cpp 文件中实现:当点击 "新建" 时,弹出⼀个模态对话框;
- 说明:在菜单项中,点击菜单项时就会触发 triggered() 信号。
4.2 非模态对话框
非模态对话框显示后独立存在,可以同时与父窗⼝进行交互,是⼀种非阻塞式对话框、
使用 QDialog::show() 函数调用。
- 非模态对话框一般在堆上创建,这是因为如果创建在栈上时,弹出的非模态对话框就会一闪而过。同时还需要设置 Qt:WA_DeleteOnClose 属性,母的是:当创建多个非模态对话框时(如打开了多个非模态窗口),为了避免内存泄漏要设置此属性。
非模态对话框适用于特殊功能设置的场合,比如查找操作,属性设置等。
示例:
4.3 混合属性对话框
混合属性对话框同时具有模态对话框和非模态对话框的属性,对话框的生成和销毁具有非模态对话框属性,功能上具有模态对话框的属性。
使用 QDialog::setModal() 函数 可以创建混合特性的对话框。通常,创建对话框时需要指定对话框的父组件。
示例:
5. Qt 内置对话框
Qt 提供了多种可复用的对话框类型,即 Qt 标准对话框。Qt 标准对话框全部继承于 QDialog类。常用标准对话框如下:
5.1 消息对话框 QMessageBox
消息对话框是应用程序中最常用的界面元素。消息对话框主要用于为用户提示重要信息,强制用户进行选择操作。
QMessageBox类 中定义了静态成员函数,可以直接调用创建不同风格的消息对话框,其中包括:
Question | 用于正常操作过程中的提问 |
Information | 用于报告正常运行信息 |
Warning | 用于报告非关键错误 |
Critical | 用于报告严重错误 |
其对应的函数原型如下:
示例1:问题提示消息对话框
void MainWindow::on_pushButton_clicked()
{
// 创建 MessageBox
QMessageBox* messageBox = new QMessageBox(this);
// 设置尺寸
messageBox->resize(400, 300);
// 设置消息对话框的标题
messageBox->setWindowTitle("Warning Message");
// 设置消息对话框的内容
messageBox->setText("Error Message!");
// 设置消息对话框类型
messageBox->setIcon(QMessageBox::Question);
// 在消息对话框上设置按钮
messageBox->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
// 弹出模态对话框,当对话框处于弹出状态的时候,代码就会在 exec 这里阻塞,一直到对话框被关闭
messageBox->exec();
// delete messageBox;
messageBox->setAttribute(Qt::WA_DeleteOnClose);
}
实现效果如下:
其中可以设置的按钮的类型如下:
🌴自定义按钮:
void MainWindow::on_pushButton_clicked()
{
// 创建 MessageBox
QMessageBox* messageBox = new QMessageBox(this);
// 设置尺寸
messageBox->resize(400, 300);
// 设置消息对话框的标题
messageBox->setWindowTitle("Warning Message");
// 设置消息对话框的内容
messageBox->setText("Error Message!");
// 设置消息对话框类型
messageBox->setIcon(QMessageBox::Question);
// 在消息对话框上设置按钮
//messageBox->setStandardButtons(QMessageBox::Open | QMessageBox::Close);
// 自定义按钮
QPushButton* button1 = new QPushButton("按钮1", messageBox);
QPushButton* button2 = new QPushButton("按钮2", messageBox);
messageBox->addButton(button1, QMessageBox::AcceptRole);
messageBox->addButton(button2, QMessageBox::AcceptRole);
// 弹出模态对话框,当对话框处于弹出状态的时候,代码就会在 exec 这里阻塞,一直到对话框被关闭
messageBox->exec();
//delete messageBox;
messageBox->setAttribute(Qt::WA_DeleteOnClose);
}
实现效果如下:
🌵更改消息对话框中的按钮类型:
void MainWindow::on_pushButton_clicked()
{
// 创建 MessageBox
QMessageBox* messageBox = new QMessageBox(this);
// 设置尺寸
messageBox->resize(400, 300);
// 设置消息对话框的标题
messageBox->setWindowTitle("Warning Message");
// 设置消息对话框的内容
messageBox->setText("Error Message!");
// 设置消息对话框类型
messageBox->setIcon(QMessageBox::Question);
// 在消息对话框上设置按钮
messageBox->setStandardButtons(QMessageBox::Open | QMessageBox::Close);
// 弹出模态对话框,当对话框处于弹出状态的时候,代码就会在 exec 这里阻塞,一直到对话框被关闭
messageBox->exec();
// delete messageBox;
messageBox->setAttribute(Qt::WA_DeleteOnClose);
}
实现效果如下:
示例2:信息提示消息对话框
void MainWindow::on_pushButton_clicked()
{
// 创建 MessageBox
QMessageBox* messageBox = new QMessageBox(this);
// 设置尺寸
messageBox->resize(400, 300);
// 设置消息对话框的标题
messageBox->setWindowTitle("Warning Message");
// 设置消息对话框的内容
messageBox->setText("Error Message!");
// 设置消息对话框类型
messageBox->setIcon(QMessageBox::Information);
// 在消息对话框上设置按钮
messageBox->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
// 弹出模态对话框,当对话框处于弹出状态的时候,代码就会在 exec 这里阻塞,一直到对话框被关闭
messageBox->exec();
// delete messageBox;
messageBox->setAttribute(Qt::WA_DeleteOnClose);
}
实现效果如下:
示例3:警告信息消息对话框
-
使用另一种更为简单的方式创建 MessageBox
void MainWindow::on_pushButton_clicked()
{
QMessageBox::warning(this, "Warning Message", "Error Message", QMessageBox::Ok | QMessageBox::Cancel);
}
实现效果如下:
示例4:错误提示消息对话框
void MainWindow::on_pushButton_clicked()
{
QMessageBox::critical(this, "Warning Message", "Error Message", QMessageBox::Ok | QMessageBox::Cancel);
}
实现效果如下:
5.2 颜色对话框 QColorDialog
颜色对话框的功能是允许用户选择颜色。继承自 QDialog 类。颜色对话框如下图示:
常用方法介绍:
1、 QColorDialog (QWidget *parent = nullptr) //创建对象的同时设置父对象
2、 QColorDialog(const QColor &initial, QWidget *parent = nullptr) //创建对象的同时通过QColor对象设置默认颜色和父对象
3、 void setCurrentColor(const QColor &color) //设置当前颜色对话框
4、 QColor currentColor() const //获取当前颜色对话框
5、 QColor getColor(const QColor &initial = Qt::white, QWidget *parent = nullptr, const QString&title = QString(), QColorDialog::ColorDialogOptions options = ColorDialogOptions()) //打开颜色选择对话框,并返回一个QColor对象
参数说明:
- initial:设置默认颜色
- parent:设置父对象
- title:设置对话框标题
- options:设置选项
6、 void open(QObject *receiver, const char *member) //打开颜色对话框
示例1:
void MainWindow::on_pushButton_clicked()
{
// 函数的返回值就是用户选择的颜色
QColor color = QColorDialog::getColor(QColor(0, 255, 255), this, "选择颜色");
qDebug() << color;
}
效果如下:
示例2:设置背景色
void MainWindow::on_pushButton_clicked()
{
// 函数的返回值就是用户选择的颜色
QColor color = QColorDialog::getColor(QColor(0, 255, 255), this, "选择颜色");
// 可以基于用户选择的颜色,修改窗口的背景色
// 第1种方式
// QString style = "background-color: rgb(" + QString::number(color.red()) + ", " + QString::number(color.green())
// + ", " + QString::number(color.blue()) + ")";
// 第2种方式
char style[1024] = { 0 };
sprintf(style, "background-color: rgb(%d, %d, %d);", color.red(), color.green(), color.blue());
this->setStyleSheet(style);
}
效果如下:
5.3 文件对话框 QFileDialog
文件对话框用于应用程序中需要打开一个外部文件或需要将当前内容存储到指定的外部文件。
常用方法介绍:
1、打开文件(一次只能打开一个文件)
QString getOpenFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = Options())
2、打开多个文件(一次可以打开多个文件)
QStringList getOpenFileNames(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = Options())
3、 保存文件
QString getSaveFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = Options())
参数说明:
- 参数1:parent 父亲
- 参数2:caption 对话框标题
- 参数3:dir 默认打开的路径
- 参数4:filter 文件过滤器
示例1:打开文件
void MainWindow::on_pushButton_open_clicked()
{
QString filePath = QFileDialog::getOpenFileName(this);
qDebug() << filePath;
}
效果如下:
示例2:保存文件
void MainWindow::on_pushButton_save_clicked()
{
QString filePath = QFileDialog::getSaveFileName(this);
qDebug() << filePath;
}
5.4 字体对话框 QFontDialog
Qt 中提供了预定义的字体对话框类 QFontDialog,用于提供选择字体的对话框部件。
示例:
void MainWindow::on_pushButton_clicked()
{
// 由于 getFont 方法第一个参数为 bool 类型,所以有此定义
bool ok = false;
// 使用 QFontDialog 的 静态方法getFont 打开字体对话框并设置默认格式
QFont font = QFontDialog::getFont(&ok);
// 获取 ok 的 bool值
qDebug() << "ok = " << ok;
//qDebug() << font;
// 获取字体
qDebug() << "字体:" << font.family();
// 获取字号
qDebug() << "字号:" << font.pointSize();
// 判断字体是否加粗
qDebug() << "是否加粗:" << font.bold();
// 判断字体是否倾斜
qDebug() << "是否倾斜:" << font.italic();
// 应用字体
ui->pushButton->setFont(font);
}
运行效果如下:
5.5 输入对话框 QInputDialog
Qt 中提供了预定义的输入对话框类:QInputDialog,用于进行临时数据输入的场合。
常用方法介绍:
1、双精度浮点型输入数据对话框
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());
2、整型输入数据对话框
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());
3、选择条目型输入数据框
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:对话框标签
- items:可供选择的条目
示例1:浮点型数据输入对话框
void MainWindow::on_pushButton_clicked()
{
double ret = QInputDialog::getDouble(this, "输入框", "浮点型");
qDebug() << ret;
}
运行效果:
示例2:整型数据输入对话框
void MainWindow::on_pushButton_2_clicked()
{
int ret = QInputDialog::getInt(this, "输入框", "整形");
qDebug() << ret;
}
运行效果:
示例3:打开选择条目对话框
void MainWindow::on_pushButton_3_clicked()
{
QStringList items;
items.push_back("123");
items.push_back("456");
items.push_back("789");
QString item = QInputDialog::getItem(this, "输入框", "条目", items);
qDebug() << item;
}
运行效果: