目录
[1.1 创建QMainWindow窗口](#1.1 创建QMainWindow窗口)
[1.2 添加按钮来触发对话框](#1.2 添加按钮来触发对话框)
[1.3 创建C++类(Dialog类)](#1.3 创建C++类(Dialog类))
[1.4 编写按钮槽函数](#1.4 编写按钮槽函数)
[1.5 对子窗口添加控件](#1.5 对子窗口添加控件)
一.什么是对话框
对话框是 GUI 程序中不可或缺的组成部分。⼀些不适合在主窗⼝实现的功能组件可以设置在对话框 中。对话框通常是⼀个顶层窗⼝,出现在程序最上层,⽤于实现短期任务或者简洁的⽤⼾交互。
目的:与用户进行短平快的交互
二.对话框的分类
1.模态和非模态对话框
两种对话框区别是打开后还能否与其他窗口交互
1.1模态对话框
**在对话框打开时,用户只能与对话框进行交互,而不能与其他窗口进行交互,直到对话框关闭。**模态对话框会阻塞程序的执行,直到用户对对话框进行操作并关闭对话框。
使⽤QDialog::exec() 函 数调⽤。
1.2非模态对话框
**非模态对话框是指在对话框打开时,用户可以同时与对话框和其他窗口进行交互,不会阻塞程序的执行。**非模态对话框允许用户在对话框打开的同时执行其他操作,而不需要等待对话框关闭。
使⽤ QDialog::show()函数调⽤。
1.2.1非模态窗口闪退问题
问题:Qt创建一个子窗口时,发现窗口创建后会闪退。
原因:①为窗口创建在栈上时,是局部变量。
②show()函数是非阻塞方式运行窗口,窗口创建后代码继续运行而退出函数,函数退出后直接销毁其中的局部变量,导致窗口显示后直接被销毁,闪退
解决方案:对于qt的三种窗口,QWidget、QMainWindow、QDialog
QDialog可以使用函数exec()来阻塞式显示窗口,这样直到窗口被关闭才会继续运行后续代码退出函数。
而对于QWidget与QMainWindow(继承于QWidget),可以使用new,将对话框创建在堆上。
⾮模态对话框⼀般在堆上创建,此时我们需要设置 Qt:WA_DeleteOnClose 属性,⽬的是:当创建多个⾮模态对话框时(如打开了多个⾮ 模态窗⼝),为了避免内存泄漏。
eg:
cpp
QPushButton* btn=new QPushButton(this);
btn->setText("button");
connect(btn,&QPushButton::clicked,[=](){
// 非模态对话框
QDialog* dlg=new QDialog(this);
dlg->resize(200,200);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->show();
2.混合属性对话框
混合属性对话框(Mixed Attribute Dialog)是指同时具有模态和非模态特性的对话框。它能在对话框显示期间阻塞其所属窗口上的其他操作,但又可以供用户继续操作其他非对话框部件。
3.Qt内置对话框
在Qt中存在许多自带的对话框,Qt 提供了多种可复⽤的对话框类型,即 Qt 标准对话框。Qt 标准对话框全部继承于QDialog类。
内置对话框 说明
QMessageBox 用于显示消息、警告、错误等信息的对话框。
QInputDialog 用于获取用户输入的对话框,可以用于获取文本、整数、浮点数等类型的输入。
QColorDialog 用于选择颜色的对话框。
QFileDialog 用于选择文件或目录的对话框。
QFontDialog 用于选择字体的对话框。
QProgressDialog 用于显示进度条的对话框。
QPrintDialog 用于打印文档的对话框。
QPageSetupDialog 用于设置页面布局的对话框。
在下一节我们会详细介绍内置对话框。
三.创建自定义对话框
1.代码方式实现
1.1 创建QMainWindow窗口
1.2 添加按钮来触发对话框
在QMainWindow窗口上,创建一个打开窗口的按钮
cpp
//mainwindow.cpp
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建一个按钮
QPushButton* button = new QPushButton("open window btn",this);
//设置按钮的大小
button->resize(300,100);
//移动按钮位置
button->move(250,200);
//按钮信号点击触发槽函数
connect(button,&QPushButton::clicked,this,&MainWindow::handle);
}
声明槽函数
cpp
//mainwindow.h
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
//声明槽函数
void handle();
private:
Ui::MainWindow *ui;
};
运行结果:
1.3 创建C++类(Dialog类)
创建一个新的类,类名为Dialog,继承QDialog类。
对dialog.h和dialog.cpp进行修改
cpp
//dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget* parent);
};
#endif // DIALOG_H
cpp
//dialog.cpp
#include "dialog.h"
Dialog::Dialog(QWidget* parent) : QDialog(parent)
{
}
1.4 编写按钮槽函数
cpp
void MainWindow::handle()
{
//创建一个对话框
Dialog * dialog = new Dialog(this);
//设置窗口的大小
dialog->resize(300,180);
//设置窗口关闭
dialog->setAttribute(Qt::WA_DeleteOnClose);
//显示窗口
dialog->show();
}
1.5 对子窗口添加控件
cpp
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget* parent);
void buttonclose();
};
#endif // DIALOG_H
cpp
dialog.cpp
#include "dialog.h"
#include<QPushButton>
#include<QLabel>
#include<QVBoxLayout>
Dialog::Dialog(QWidget* parent) : QDialog(parent)
{
//创建垂直布局
QVBoxLayout* layout = new QVBoxLayout();
this->setLayout(layout);
//创建标签和按钮
QLabel * label = new QLabel("This is a window",this);
QPushButton* button = new QPushButton("close",this);
//将控件添加进布局中
layout->addWidget(label);
layout->addWidget(button);
//进行按钮槽函数链接
connect(button,&QPushButton::clicked,this,&Dialog::buttonclose);
}
void Dialog::buttonclose()
{
//关闭子窗口
this->close();
}
运行结果:
2.图形化实现
2.1创建QMainWindow窗口
2.2 创建一个按钮控件
在界面中拖拽进一个PushButton控件
2.3 新建一个ui文件
2.4 在界面中创建按钮和标签
2.5 编写创建按钮的槽函数
cpp
void MainWindow::on_pushButton_clicked()
{
//创建窗口
Dialog* dialog = new Dialog(this);
//关闭窗口释放内存
dialog->setAttribute(Qt::WA_DeleteOnClose);
//展示窗口
dialog->show();
}
2.6 编写关闭按钮槽函数
cpp
void Dialog::on_pushButton_clicked()
{
//关闭窗口
this->close();
}
运行结果: