文章目录
- 创建普通的对话框
- 对话框的内存泄露问题
- 自定义对话框
- 模态式对话框
- QMessageBox(消息对话框)
- QColorDialog(颜色对话框)
- QFileDialog(文件对话框)
- QFontDialog(字体对话框)
- QInputDialog(输入对话框)
- QFiledialog:文件对话框
- QColorDialog:颜色对话框
- QFontDialog:字体对话框
- QInputDialog:输入对话框
- QMessageBox:消息框
创建普通的对话框
实现点击按钮后弹出对话框
cpp
// 创建一个按钮,点击之后弹出对话框
QPushButton *b = new QPushButton(this);
b->setText("弹出对话框"); b->move(350, 300);
// 设置按钮的槽函数
connect(b, &QPushButton::clicked, this, [=](){
// 创建对话框
QDialog *d = new QDialog(this);
// 设置对话框尺寸
d->resize(200, 200);
// 通过 show 方法显示对话框
d->show();
});
对话框的内存泄露问题
上述的方式其实会有内存泄漏的问题。
首先按钮点击的槽函数是在堆上创建一个新的对话框对象,并且在函数执行完之后并没有释放掉这个对象,虽然这个对话框对象是挂在了父窗口上的。但难免会有些场景下,在没有关闭窗口的时候创建了很多个对话框对象都没有释放,那就很可以能会导致内存不够程序崩溃。
为了解决这个问题,就必须要在关闭对话框的时候将这个对象释放掉。先来看一种情况:直接在对话框弹出后就 delete 掉。
cpp
// 设置按钮的槽函数
connect(b, &QPushButton::clicked, this, [=](){
// 创建对话框
QDialog *d = new QDialog(this);
// 设置对话框尺寸
d->resize(200, 200);
// 通过 show 方法显示对话框
d->show();
delete d;
});
这样子写就会导致对话框直接就释放掉了,根本没有操作的时间。所以就得在对话框关闭时才释放对象。
因此为了解决这种情况,Qt的对话框内置了一个属性,Qt::WA_DeleteOnClose 这个属性设置了之后,对话框对象就会在关闭对话框的时候释放掉,非常的方便。
cpp
// 设置按钮的槽函数
connect(b, &QPushButton::clicked, this, [=](){
// 创建对话框
QDialog *d = new QDialog(this);
// 设置对话框尺寸
d->resize(200, 200);
// 通过 show 方法显示对话框
d->show();
d->setAttribute(Qt::WA_DeleteOnClose);
});
自定义对话框
想要在主窗口上的对话框添加内容,就需要新建一个类继承 QDialog 类,然后在新建类上操作。
有两种方法,纯代码编写和 ui 界面编写,这里以纯代码演示。
先来看看项目结构
接下来就可以在 mydialog.cpp 文件中编写 MyDialog 类的构造函数从而实现添加一些内容。
首先编写 mydialog.cpp 实现对话框内容
cpp
#include "mydialog.h"
#include "ui_mydialog.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
MyDialog::MyDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::MyDialog)
{
ui->setupUi(this);
// 创建一个布局管理器
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, [=](){
this->close();
});
}
MyDialog::~MyDialog()
{
delete ui;
}
接着编写主窗口,实现按钮点击弹出对话框,注意此时创建的对话框类型就不是内置的 QDialog 了,而是我们自己新建的对话框类
cpp
// 创建一个按钮,点击之后弹出对话框
QPushButton *b = new QPushButton(this);
b->setText("弹出对话框"); b->move(350, 300);
// 设置按钮的槽函数
connect(b, &QPushButton::clicked, this, [=](){
// 创建对话框
MyDialog *d = new MyDialog(this);
// 设置对话框尺寸
d->resize(200, 200);
// 通过 show 方法显示对话框
d->show();
d->setAttribute(Qt::WA_DeleteOnClose);
看看效果:
模态式对话框
模态:对话框显示后,除非关闭对话框,否则无法再操作父窗口,属于阻塞式对话框
非模态:对话框显示后可以继续操作父窗口,属于非阻塞式对话框
非模态效果:
模态效果:
非模态和模态的设置就是在对话框对象调用显示函数的不同
- 模态:调用 exec 函数显示
- 非模态:调用 show 函数显示
QMessageBox(消息对话框)
消息对话框是应用程序中最常用的界面元素。消息对话框主要用于为用户提示重要信息,强制用户进行选择操作。
对话框类型
消息对话框是需要设置类型的,例如:警告、错误等类型。可以通过 setIcon 方法去设置类型,不同的类型会对应出不同的图标。
- QMessageBox::Question:提问类型
- QMessageBox::Information:正常运行类型
- QMessageBox::Warning:警告类型
- QMessageBox::Critical:错误类型
对话框按钮
Qt 已经为消息对话框内置了许多的按钮类型
通过 setStandardButtons 函数就可以设置了。
当然消息对话框也支持添加自定义的按钮控件,并且也可以支持槽函数,但是相对起来使用内置的更方便
接收对话框返回值
当点击了对话框的内置按钮后,会返回这个按钮的类型,是可以被接收到的。
因此利用这个性质,就可以根据接收到的类型去实现相应的业务处理
演示
首先创建一个按钮用于弹出对话框,并创建一个 label 控件显示出点击了对话框后的处理结果
编写按钮点击的槽函数代码
cpp
void MainWindow::on_pushButton_clicked()
{
// 创建消息对话框
QMessageBox *msg = new QMessageBox(this);
// 设置对话框标题
msg->setWindowTitle("警告");
// 设置对话框的文本
msg->setText("请选择");
// 设置对话框类型
msg->setIcon(QMessageBox::Warning);
// 设置对话框按钮
msg->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
// 接收对话框的按钮类型
int res = msg->exec();
// 根据类型显示不同信息
if(res == QMessageBox::Ok)
ui->label->setText("OK");
if(res == QMessageBox::Cancel)
ui->label->setText("Cancel");
// 设置自动释放属性
msg->setAttribute(Qt::WA_DeleteOnClose);
}
其他创建方式
在 QMessageBox 中有个静态的函数 information 可以直接创建一个临时的对话框对象,并返回对话框的点击值。非常的方便
cpp
static int information(QWidget *parent,
const QString &title,
const QString& text,
int button0,
int button1 = 0,
int button2 = 0);
- 参数一:父对象
- 参数二:对话框标题
- 参数三:对话框文本
- 参数四五六:对话框的按钮类型
cpp
void MainWindow::on_pushButton_clicked()
{
int res = QMessageBox::information(this, "警告", "选择",
QMessageBox::Ok | QMessageBox::Cancel);
if(res == QMessageBox::Ok)
ui->label->setText("OK");
if(res == QMessageBox::Cancel)
ui->label->setText("Cancel");
}
效果与上述的一样的
QColorDialog(颜色对话框)
这个对话框主要是用来选择颜色的。
主要的方法有:
cpp
// 创建对象的同时设置父对象
QColorDialog (QWidget *parent = nullptr);
// 创建对象的同时通过QColor 对象设置默认颜色和父对象
QColorDialog(const QColor &initial, QWidget *parent = nullptr);
// 设置当前颜色对话框
void setCurrentColor(const QColor &color);
// 获取当前颜色对话框
QColor currentColor() const;
// 打开颜色选择对话框,并返回一个 QColor 对象
QColor getColor(const QColor &initial = Qt::white,
QWidget *parent = nullptr,
const QString &title = QString(),
QColorDialog::ColorDialogOptions options = ColorDialogOptions());
- const QColor &initial:初始化默认颜色
- QWidget *parent:父对象
- const QString &title:对话框标题
- QColorDialog::ColorDialogOptions:对话框的外观和行为
案例
实现一个按钮弹出对话框,接收到QColor 对象后修改 label 的背景颜色
cpp
void MainWindow::on_pushButton_clicked()
{
// 创建颜色对话框
QColorDialog *c = new QColorDialog(this);
// 打开对话框设置默认颜色为红色并获取返回的QColor对象
QColor res = c->getColor(QColor(255, 0, 0));
// 根据获取到的颜色使用QSS改变 label的背景颜色
char qss[1024] = {0};
sprintf(qss, "background-color: rgb(%d, %d, %d);",
res.red(), res.green(), res.blue());
ui->label->setStyleSheet(qss);
}
QFileDialog(文件对话框)
文件对话框用于应用程序中需要打开⼀个外部文件或需要将当前内容存储到指定的外部文件。
常用方法:
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 getOpenFileNames(QWidget *parent = nullptr,
const QString &caption = QString(),
const QString &dir = QString(),
const QString &filter = QString(),
QString *selectedFilter = nullptr,
QFileDialog::Options options = Options());
// 保存文件
QString getSaveFileName(QWidget *parent = nullptr,
const QString &caption = QString(),
const QString &dir = QString(),
const QString &filter = QString(),
QString *selectedFilter = nullptr,
QFileDialog::Options options = Options());
- QWidget *parent:父对象
- const QString &caption:caption 对话框标题
- const QString &dir:默认打开的路径
- const QString &filter:文件过滤器
案例
将打开/保存文件的路径打印到 label
cpp
void MainWindow::on_pushButton_clicked()
{
QString filename = QFileDialog::getOpenFileName(this,
"打开文件",
"D:\\",
"*.png");
ui->label->setText(filename);
}
void MainWindow::on_pushButton_2_clicked()
{
QString filename = QFileDialog::getSaveFileName(this,
"保存文件",
"D:\\",
"*.txt");
ui->label->setText(filename);
}
QFontDialog(字体对话框)
用于提供选择字体的对话框
主要方法:
cpp
// 打开字体对话框并获取所选择的字体样式
static QFont getFont(bool *ok,
const QFont &initial,
QWidget *parent = nullptr,
const QString &title = QString(),
FontDialogOptions options = FontDialogOptions());
- bool *:输入输出型bool参数
- const QFont &initial:字体对话框的初始选择
案例
修改 label 的字体为字体对话框中选择的字体样式
cpp
void MainWindow::on_pushButton_clicked()
{
bool flag;
QFont font = QFontDialog::getFont(&flag, QFont("黑体", 10));
char qss[1024] = {0};
sprintf(qss, "font-family: '%s';font-size: %dpt;",
font.family().toUtf8().data(), font.pointSize());
ui->label->setStyleSheet(qss);
}
QInputDialog(输入对话框)
⽤于进行临时数据输入的场合
常用方法:
cpp
// 弹出整形输入对话框,并获取输入的整数
static int getInt(QWidget *parent,
const QString &title,
const QString &label,
int value = 0,
int minValue = -2147483647,
int maxValue = 2147483647,
int step = 1,
bool *ok = nullptr,
Qt::WindowFlags flags = Qt::WindowFlags());
// 弹出浮点型输入对话框,并获取输入的浮点数
static double getDouble(QWidget *parent,
const QString &title,
const QString &label,
double value = 0,
double minValue = -2147483647,
double maxValue = 2147483647,
int decimals = 1,
bool *ok = nullptr,
Qt::WindowFlags flags = Qt::WindowFlags());
// 弹出条目输入对话框,并获取选择的条目
static 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);
案例
cpp
void MainWindow::on_pushButton_clicked()
{
int result = QInputDialog::getInt(this, "整数", "请输入一个整数: ");
ui->label->setText(QString::number(result));
}
void MainWindow::on_pushButton_2_clicked()
{
double result = QInputDialog::getDouble(this, "浮点数", "请输入一个浮点数: ");
ui->label_2->setText(QString::number(result));
}
void MainWindow::on_pushButton_3_clicked()
{
// 创建条目
QStringList items;
items.push_back("可乐");
items.push_back("雪碧");
QString result = QInputDialog::getItem(this, "条目", "请选择: ", items);
ui->label_3->setText(result);
}