Qt学习之九:深入对话框

来源:互联网 发布:北京域名百科 编辑:程序博客网 时间:2024/06/08 12:37

一、对话框简介
对话框通常是一个顶层窗口,出现在程序的最上层,用于实现短期任务或者简洁的用户交互。Qt中使用QDialog类来实现对话框。 就像主窗口一样,我们通常会设计一个类继承 QDialog。QDialog(及其子类,以及所有 Qt::Dialog 类型的类)的对于其 parent 指针都有额外的解释:如果 parent 为 NULL,则该对话框会作为一个顶层窗口,否则则作为其父组件的子对话框(此时,其默认出现的位置是 parent 的中心)。顶层窗口与非顶层窗口的区别在于,顶层窗口在任务栏会有自己的位置,而非顶层窗口则会共享其父组件的位置。

就像主窗口一样,我们通常会设计一个类继承 QDialog。QDialog(及其子类,以及所有 Qt::Dialog 类型的类)的对于其 parent 指针都有额外的解释:如果 parent 为 NULL,则该对话框会作为一个顶层窗口,否则则作为其父组件的子对话框(此时,其默认出现的位置是 parent 的中心)。顶层窗口与非顶层窗口的区别在于,顶层窗口在任务栏会有自己的位置,而非顶层窗口则会共享其父组件的位置。

void MainWindow::open(){    QDialog dialog;//对话框作为单独的主窗口    dialog.setWindowTitle("Hello,dialog!");    dialog.exec();}void MainWindow::open(){    QDialog dialog(this);    dialog.setWindowTitle("Hello,dialog!");    dialog.exec();}

这里写图片描述

对话框分为模态对话框和非模态对话框。所谓模态对话框,就是会阻塞同一应用程序中其它窗口的输入。模态对话框很常见,比如“打开文件”功能。你可以尝试一下记事本的打开文件,当打开文件对话框出现时,我们是不能对除此对话框之外的窗口部分进行操作的。与此相反的是非模态对话框,例如查找对话框, 我们可以在显示着查找对话框的同时, 继续对记事本的内容进行编辑。

Qt 支持模态对话框和非模态对话框。其中, Qt 有两种级别的模态对话框:应用程序级别的模态和窗口级别的模态,默认是应用程序级别的模态。应用程序级别的模态是指,当该种模态的对话框出现时,用户必须首先对对话框进行交互,直到关闭对话框,然后才能访问程序中其他的窗口。窗口级别的模态是指,该模态仅仅阻塞与对话框关联的窗口,但是依然允许用户与程序中其它窗口交互。窗口级别的模态尤其适用于多窗口模式。
Qt 使用 QDialog::exec() 实现应用程序级别的模态对话框,使用 QDialog::open() 实现窗口级别的模态对话框,使用 QDialog::show() 实现非模态对话框。

非模态对话框:

```void MainWindow::open(){    QDialog dialog;    dialog.setWindowTitle("Hello,dialog!");    dialog.show();}

采用show()函数后,对话框一闪而过。这是因为, show() 函数不会阻塞当前线程,对话框会显示出来,然后函数立即返回,代码继续执行。注意, dialog 是建立在栈上的, show() 函数返回, MainWindow::open() 函数结束, dialog 超出作用域被析构,因此对话框消失了。知道了原因就好改了,我们将 dialog 改成堆上建立,当然就没有这个问题了:

void MainWindow::open(){    QDialog* dialog  = new QDialog;    dialog->setWindowTitle("Hello,dialog!");    dialog->show();}

这里写图片描述
但是这里存在一个dialog指针内存泄漏的问题,解决之道可以是:调用deleteLater()函数或者设置dialog的WindowAttribute:

void MainWindow::open(){    QDialog* dialog  = new QDialog;    dialog->setAttribute(Qt::WA_DeleteOnClose);//or:dialog->deleteLater();    dialog->setWindowTitle(tr("Hello,dialog!"));    dialog->show();}

setAttribute()函数设置对话框关闭时,自动销毁对话框。
deleteLater()函数则会在当前事件循环结束时销毁该对话框。

二、对话框数据传递

对话框与主窗口之间的数据交互相当重要。本节主要讲解如何在对话框和主窗口之间进行数据交互。 模态对话框使用了 exec() 函数将其显示出来。 exec() 函数的真正含义是开启一个新的事件循环(我们会在后面的章节中详细介绍有关事件的概念)。所谓事件循环,可以理解成一个无限循环。 Qt 在开启了事件循环之后,系统发出的各种事件才能够被程序监听到。这个事件循环相当于一种轮询的作用。既然是无限循环,当然在开启了事件循环的地方,代码就会被阻塞,后面的语句也就不会被执行到。因此,对于使用了 exec() 显示的模态对话框,我们可以在 exec() 函
数之后直接从对话框的对象获取到数据值。

void MainWindow::open(){    QDialog dialog(this);   // QDialog* dialog  = new QDialog;  //  dialog->setAttribute(Qt::WA_DeleteOnClose);//or:dialog->deleteLater();    dialog.setWindowTitle(tr("Hello,dialog!"));    dialog.exec();    qDebug()<<dialog.result();}

对于模态对话框,可以在执行exec()函数之后获取对话框中的数据。

对于非模态对话框,需要使用信号槽机制。

0 0