# 对话框 ​ 对话框通常是一个顶层窗口,出现在程序的最上层,用于实现短期任务或和用户进行交互。Qt使用`QDialog`类实现对话框,`Dialog`类继承自`QWidget`类。并且`QDialog`类对父对象有额外的解释:若不向`QDialog`对象指定父对象,则代表该`Dialog`对象是一个顶级窗口,否则为父对象的子对话框(默认出现在父窗口的中心)。 根据对话框对父窗口的影响,可以分为: 1. 模态对话框 2. 非模态对话框 ## 一、模态对话框 ​ 模态对话框又可以向下细分为`程序模态`和`窗口模态`。程序模态将会阻塞程序,用户必须完成对话框的交互才能访问程序的其他窗口,而`窗口模态`则仅仅阻塞调用`模态窗口`的窗口。 ​ Qt使用`QDialog::exec()`实现模态对话框。 ## 二、非模态对话框 ​ 非模态对话框对程序不进行任何阻塞,用户可以忽略掉非模态对话框请求的交互。 ​ Qt使用`QDialog::show()`实现非模态对话框。 注意:由于非模态对话框不会阻塞线程,当函数结束时,非模态对话框就会消失,为了解决这个问题,可以`将非模态对话框建立在堆上`。(注意防止内存泄漏) **防止内存泄漏的两种方法** 1. 为非模态对话框指针指定父对象。 2. 使用`WindowAttribute`属性: ```c++ void MainWindow::open() { QDialog *dialog = new QDialog; dialog->setAttribute(Qt::WA_DeleteOnClose);//对话框关闭时自动销毁指针 dialog->setWindowTitle(tr("Hello, dialog!")); dialog->show(); } ``` `setAttribute()`函数设置对话框关闭时,自动销毁对话框。另外,`QObject`还有一个`deleteLater()`函数,该函数会在当前事件循环结束时销毁该对话框(具体到这里,需要使用`exec()`开始一个新的事件循环)。 ​ 如果是 show() 函数的话,只能使用 dialog->setAttribute(Qt::WA_DeleteOnClose);如果要使用 dialog->deleteLater(),则必须使用 exec() 函数。这是因为 deleteLater() 会在事件循环结束时执行,show() 不开始新的事件循环,所以会一闪而过。